Интеграция с OrangeData для 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Интеграция с OrangeData для 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

Интеграция с OrangeData для 1С-Битрикс

OrangeData — облачный фискальный регистратор, который работает по схеме «касса как сервис». Физической кассы у магазина нет: OrangeData сам хранит и обслуживает оборудование, а вы получаете API для отправки чеков. Это удобно, пока не начинаете разбираться в деталях: авторизация через сертификаты X509, асинхронная фискализация, специфическая схема атрибутов чека под 54-ФЗ. Стандартного модуля в Битрикс нет, всё реализуется через кастомный обработчик платёжной системы.

Как работает OrangeData API

OrangeData использует REST API с взаимной TLS-аутентификацией. Это не просто токен в заголовке — нужно клиентское X509-сертификат, который выдаётся при регистрации. Каждый запрос к API подписывается приватным ключом из этого сертификата.

Основные эндпоинты:

  • POST /api/v2/documents/ — отправить документ (чек прихода, возврата, коррекции)
  • GET /api/v2/documents/{id} — получить результат фискализации по идентификатору

Важный момент: фискализация асинхронная. После POST вы получаете 202 Accepted, а не готовый чек. Реальный фискальный признак появляется через несколько секунд или минут — нужно опрашивать GET-эндпоинт или ждать callback.

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

$document = [
    'id' => uniqid('', true), // уникальный идентификатор документа
    'inn' => $inn,
    'group' => 'Main',
    'key' => $signatureKeyName, // имя ключа из личного кабинета OrangeData
    'content' => [
        'type' => 1, // 1 - приход, 2 - возврат прихода
        'positions' => $this->buildPositions($payment),
        'checkClose' => [
            'payments' => [
                [
                    'type' => $this->getPaymentType($payment), // 1-наличные, 2-безнал
                    'amount' => $payment->getSum(),
                ],
            ],
            'taxationSystem' => 0, // 0-ОСН, 1-УСН доход, 2-УСН доход-расход
        ],
        'customerContact' => $this->getCustomerContact($order),
    ],
];

Поле positions — массив позиций чека. Каждая позиция содержит quantity, price, tax (код ставки НДС), text (наименование), paymentMethodType и paymentSubjectType. Последние два поля — требование 54-ФЗ с 2019 года: нужно явно указать, что продаётся (товар, услуга, работа) и каким способом (предоплата, полный расчёт).

private function buildPositions(\Bitrix\Sale\Payment $payment): array
{
    $order = $payment->getOrder();
    $basket = $order->getBasket();
    $positions = [];

    foreach ($basket as $item) {
        $positions[] = [
            'quantity'           => $item->getQuantity(),
            'price'              => $item->getPrice(),
            'tax'                => $this->mapVatRate($item->getField('VAT_RATE')),
            'text'               => $item->getField('NAME'),
            'paymentMethodType'  => 4, // 4 - полный расчёт
            'paymentSubjectType' => 1, // 1 - товар
        ];
    }

    // Доставка как отдельная позиция
    if ($order->getDeliveryPrice() > 0) {
        $positions[] = [
            'quantity'           => 1,
            'price'              => $order->getDeliveryPrice(),
            'tax'                => 6, // без НДС
            'text'               => 'Доставка',
            'paymentMethodType'  => 4,
            'paymentSubjectType' => 4, // 4 - услуга
        ];
    }

    return $positions;
}

TLS-аутентификация: настройка в PHP

Отправка запросов с клиентским сертификатом через cURL:

private function apiRequest(string $method, string $path, array $data = []): array
{
    $ch = curl_init('https://api.orangedata.ru:12003' . $path);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_CUSTOMREQUEST  => $method,
        CURLOPT_POSTFIELDS     => json_encode($data),
        CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
        CURLOPT_SSLCERT        => $this->certPath,       // путь к .crt
        CURLOPT_SSLKEY         => $this->keyPath,        // путь к .key
        CURLOPT_CAINFO         => $this->caPath,         // корневой сертификат OrangeData
        CURLOPT_SSL_VERIFYPEER => true,
    ]);

    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    if ($httpCode === 202) {
        return ['status' => 'queued'];
    }

    return json_decode($response, true);
}

Сертификаты и ключи хранятся вне webroot — например, в /local/certs/orangedata/. Пути передаются через настройки обработчика платёжной системы. Никогда не кладите .key-файл в public_html.

Асинхронная фискализация: polling через агентов Битрикс

После отправки документа нужно дождаться фискального признака. Реализация через агента:

  1. После успешного POST сохраняем в b_sale_order_props поля ORANGEDATA_DOC_ID и ORANGEDATA_STATUS = pending.
  2. Агент OrangeDataCheckAgent запускается каждую минуту, выбирает заказы с ORANGEDATA_STATUS = pending, опрашивает GET /api/v2/documents/{id}.
  3. Когда статус меняется на done — сохраняем фискальные данные (fn, fd, fpd, ссылка на чек) и меняем ORANGEDATA_STATUS = done.
  4. Фискальные данные отправляются покупателю по email через событие SALE_NEW_ORDER или отдельным письмом.
public static function run(): string
{
    $pendingOrders = self::getPendingOrders();
    foreach ($pendingOrders as $orderId => $docId) {
        $result = self::checkDocumentStatus($docId);
        if (($result['status'] ?? '') === 'done') {
            self::saveFiscalData($orderId, $result);
        }
    }
    return __CLASS__ . '::run();';
}

Возвраты

При возврате отправляется документ с type: 2 (возврат прихода). Сумма и состав позиций должны совпадать с оригиналом (при полном возврате) или содержать только возвращаемые позиции (при частичном). OrangeData не проверяет связь с исходным документом по ID — это ваша ответственность.

Возврат запускается из обработчика события OnSaleOrderRefund или из административной части при ручной обработке возврата.

Тестовый контур

OrangeData предоставляет тестовый API: https://apip.orangedata.ru:12003. Тестовые сертификаты выдаются отдельно. В тестовом режиме фискализация проходит через виртуальную кассу, реальных ФН нет. Переключение между контурами — через параметр обработчика USE_TEST_API.

Сроки

Состав Срок
Базовая интеграция (приход + возврат) 4–5 дней
+ Асинхронный polling + email с чеком +2 дня
+ Частичные возвраты + маппинг ставок НДС +1 день