Інтеграція 1С-Бітрікс з POS-терміналами

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Інтеграція 1С-Бітрікс з POS-терміналами
Середня
~1-2 тижні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • 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
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Інтеграція 1С-Бітрікс з POS-терміналами

Інтернет-магазин приймає оплату онлайн, а в точках самовивозу — через POS-термінал. Замовлення з онлайну потрапляють у 1С, але статус оплати на терміналі і в Бітрікс розходяться: касир бачить «оплачено», менеджер у CRM — «очікує оплати». Плюс 54-ФЗ вимагає, щоб при оплаті через POS видавався фіскальний чек. Інтеграція вирішує три завдання одночасно: синхронізацію статусу оплати, видачу чека і оновлення залишків.

Варіанти POS-обладнання та протоколи

Робота з POS у Бітрікс залежить від конкретного обладнання та його API:

  • Еватор — REST API, є готовий модуль на Marketplace Бітрікс (evotor.kassa)
  • Атол Онлайн — REST API для фіскалізації, інтеграція через модуль atol.online або кастомно
  • МТС Каса, Лайтбокс — REST API, кастомна інтеграція
  • Ingenico, VeriFone — немає публічного HTTP API, інтеграція через middleware (1С або окремий сервіс)

Для вбудованих POS з API на рівні REST — інтеграція напряму з Бітрікс. Для терміналів без прямого API — через посередника, зазвичай 1С:Роздрібна торгівля або окремий Windows-сервіс.

Схема інтеграції через Еватор

Еватор — найбільш типовий випадок для роздрібної торгівлі. Схема:

[Бітрікс] <---> [Еватор API] <---> [Смарт-термінал Еватор]
  1. Замовлення в Бітрікс переходить у статус «Очікує оплати в магазині»
  2. Касир відкриває замовлення на терміналі (або воно передається автоматично)
  3. Покупець оплачує на POS
  4. Еватор фіксує транзакцію, надсилає webhook у Бітрікс
  5. Бітрікс переводить замовлення в «Оплачено», створює запис про оплату

Обробник платіжної системи в Бітрікс

Інтеграція з POS реалізується як кастомна платіжна система:

// /local/modules/custom.pos/install/handlers/pos.php

namespace Custom\Pos\Handler;

use Bitrix\Sale\PaySystem\ServiceHandler;
use Bitrix\Sale\PaySystem\ServiceResult;
use Bitrix\Main\Request;
use Bitrix\Sale\Order;

class PosPaymentHandler extends ServiceHandler
{
    // Викликається при ініціації оплати через POS
    public function initiatePay(
        \Bitrix\Sale\Payment $payment,
        Request $request = null
    ): ServiceResult {
        $result = new ServiceResult();

        $order = $payment->getOrder();
        $orderId = $order->getId();
        $amount = $payment->getSum();
        $currency = $payment->getCurrencyCode();

        // Передаємо замовлення в Еватор
        $evotor = new EvoktorApiClient($this->service->getField('EVOTOR_TOKEN'));
        $response = $evotor->createReceipt([
            'order_id' => $orderId,
            'total' => $amount,
            'currency' => $currency,
            'items' => $this->buildReceiptItems($order),
        ]);

        if (!$response['success']) {
            $result->addError(new \Bitrix\Main\Error($response['error']));
            return $result;
        }

        // Зберігаємо transaction_id для подальшої перевірки
        $payment->setField('PS_INVOICE_ID', $response['transaction_id']);

        return $result;
    }

    // Webhook: Еватор повідомляє про успішну оплату
    public function processRequest(
        \Bitrix\Sale\Payment $payment,
        Request $request
    ): ServiceResult {
        $result = new ServiceResult();

        $data = json_decode($request->getInput(), true);

        // Верифікуємо підпис Еватора
        $signature = $request->getHeader('X-Evotor-Signature');
        if (!$this->verifySignature($data, $signature)) {
            $result->addError(new \Bitrix\Main\Error('Invalid signature'));
            return $result;
        }

        if ($data['status'] === 'PAID') {
            $result->setOperationType(ServiceResult::MONEY_COMING);
            $result->setPaid('Y');
        }

        return $result;
    }

    private function buildReceiptItems(Order $order): array
    {
        $items = [];
        /** @var \Bitrix\Sale\Basket $basket */
        $basket = $order->getBasket();

        foreach ($basket as $basketItem) {
            $items[] = [
                'name'     => $basketItem->getField('NAME'),
                'quantity' => $basketItem->getQuantity(),
                'price'    => $basketItem->getPrice(),
                'vat'      => 'VAT20',  // ПДВ 20%
            ];
        }

        return $items;
    }
}

Фіскалізація: 54-ФЗ

При оплаті через POS обов'язковий касовий чек. Три варіанти:

  1. POS із вбудованим ФН (Еватор, МТС Каса) — чек друкується прямо на терміналі при оплаті
  2. POS без ФН + онлайн-каса — термінал фіксує факт оплати, Бітрікс надсилає дані до хмарної каси (Атол Онлайн, OFD.ru)
  3. Інтеграція через 1С — 1С:Роздрібна торгівля фіскалізує, Бітрікс отримує статус через обмін

Якщо використовується варіант 2, у Бітрікс потрібен обробник події OnSaleOrderPaid:

\Bitrix\Main\EventManager::getInstance()->addEventHandler(
    'sale', 'OnSaleOrderPaid',
    function (\Bitrix\Main\Event $event) {
        $order = $event->getParameter('ENTITY');
        $payment = $event->getParameter('PAYMENT');

        // Перевіряємо, що це POS-оплата (не онлайн)
        $paySystemId = $payment->getPaymentSystemId();
        if ($paySystemId !== POS_PAYSYSTEM_ID) {
            return;
        }

        // Надсилаємо в Атол Онлайн
        AtolOnlineService::sendReceipt($order, $payment, 'sell');
    }
);

Синхронізація залишків після POS-продажу

Коли через POS-термінал продається товар із магазину (не під онлайн-замовлення), залишки потрібно списати і в Бітрікс:

// Списання залишків на складі при POS-продажу
\Bitrix\Catalog\StoreProductTable::decreaseProductQuantity(
    $productId,
    $storeId,
    $quantity
);

// Перерахунок доступної кількості в каталозі
CCatalogProduct::getProductData($productId, ['QUANTITY' => true]);

На практиці синхронізація залишків при POS-продажах — найболючіша частина: термінал може працювати офлайн, транзакції накопичуються і надходять пакетом. Потрібна черга операцій та ідемпотентна обробка: якщо одна і та ж транзакція прийшла двічі (повтор webhook), не списувати залишки повторно.

Ідемпотентність webhook-обробника

// Перевіряємо, чи не оброблено вже цей transaction_id
$existing = \Bitrix\Sale\PaySystem\Manager::getList([
    'filter' => ['PS_INVOICE_ID' => $transactionId],
    'select' => ['ID'],
])->fetch();

if ($existing) {
    // Вже оброблено — повертаємо 200 без повторної дії
    return (new ServiceResult())->setOperationType(ServiceResult::MONEY_COMING);
}

Терміни розробки

Етап Зміст Термін
Аналіз POS-обладнання та API Документація, тест-стенд терміналу 1–2 дні
Розробка платіжного обробника Модуль у /local/, webhook-ендпоінт 3–5 днів
Фіскалізація (якщо немає вбудованої) Інтеграція з Атол Онлайн або аналогом 2–3 дні
Синхронізація залишків Списання через StoreProductTable 1–2 дні
Тестування на реальному терміналі Оплата, скасування, чек, залишки 2–3 дні