До змісту

vending-esp32-monobank — оплата Monobank QR для кавового автомата на ESP32

Роль
Соло-архітектор embedded та хмарного IoT
Період
вер. 2026
vending-esp32-monobank — оплата Monobank QR для кавового автомата на ESP32

Огляд

Платіжний контролер, який дає комерційному кавовому автомату Rheavendors приймати оплату через QR Monobank напряму — без платіжного посередника й без абонплати. Покупець сканує QR-код і платить у Monobank (або через Apple Pay / Google Pay); гроші потрапляють на рахунок ФОП власника під 1.3% банку. Cloudflare Worker перевіряє платіж у Monobank і ставить команду в чергу, а ESP32 на автоматі забирає її й нараховує кредит через плату з оптопарами, під’єднану до монетного роз’єму автомата. Далі покупець натискає кнопку напою, як зазвичай.

Це замінює сторонні платіжні термінали, які зазвичай беруть абонплату за кожен автомат (близько 150–250 грн на місяць) і 2.5–3.5% з кожної транзакції.

Перевірено наскрізно на автоматі замовника реальними платежами Monobank: оплачене сканування QR нараховує кредит, і напій наливається; кожен із чотирьох цінових каналів нараховує свою суму.


Як це працює

Крок Що відбувається
1 Покупець сканує надруковану QR-наліпку; кожна наліпка відповідає ціновому каналу, а ціна задана на сервері
2 Monobank приймає платіж і викликає вебхук Cloudflare Worker
3 Worker не довіряє тілу вебхука: повторно запитує рахунок в API Monobank і перевіряє статус, референс та що сума дорівнює ціні каналу. Повторний вебхук того ж рахунку ігнорується
4 Команда стає в чергу Durable Object окремого автомата — першим прийшов, першим пішов, діє 15 хвилин — і лежить там, доки її не підтверджено
5 ESP32 через 4G USB Wi-Fi роутер опитує шлюз по HTTPS кожні 3 секунди й перевіряє вхід Ready автомата
6 Він видає імпульс 500 мс через канал оптопар HY-M158 (PC817) на монетний роз’єм J4 автомата, і з’являється кредит
7 ESP32 підтверджує виконання, і команда зникає з черги. Ідентифікатор останньої транзакції зберігається в енергонезалежній пам’яті, тож повтор ніколи не зарахує двічі

Архітектура

Потік оплати: покупець сканує QR і платить у Monobank; Cloudflare Worker перевіряє рахунок у банку й ставить команду в чергу Durable Object окремого автомата; ESP32 через 4G-роутер її забирає й подає імпульс на плату оптопар HY-M158, під'єднану до монетного роз'єму J4

Апаратна частина на один автомат — ESP32 DevKit, 4G USB Wi-Fi роутер, 8-канальна плата HY-M158 і окремий блок живлення 5 В: разом близько 750–800 грн.


Ключові рішення

Рішення Чому
HTTP-опитування й Durable Object замість MQTT-брокера Перший план був MQTT через хмарний брокер. На безкоштовному плані Cloudflare черга у Workers KV не працює: KV дозволяє 1 000 записів чи list на добу (опитування щосекунди вичерпало б це приблизно за 17 хвилин) і кешує відсутні ключі до 60 секунд, тож оплачена команда могла лишатися невидимою. Durable Object однопотоковий і узгоджений одразу. Бюджет запитів пораховано на автомат — близько 30 000 на добу при опитуванні раз на 3 секунди, цього вистачає на три автомати на безкоштовному плані, а як масштабувати, описано
Ніколи не довіряти вебхуку Банк перепитується про рахунок щоразу. Ціни зафіксовані на сервері, а параметр ?price= у посиланні на оплату ігнорується
Черга з підтвердженням: нічого не губиться, нічого не зараховується двічі Команду видаляють лише після підтвердження імпульсу від ESP32. Дві оплати приходять по черзі, жодна не перезаписує іншу, а непідтверджена команда спливає, а не спрацьовує пізніше
Гальванічна розв’язка й окреме живлення Ізоляція 5000 В між платою автомата на 12/24 В і логікою ESP32 на 3.3 В. ESP32 і модем живляться від власного блока 5 В, ніколи від плати автомата: піки струму модема (до 1.5–2 А) перевантажили б стабілізатор на 300–400 мА
Поважати власний стан автомата Імпульс надсилається лише тоді, коли автомат готовий приймати кредит. Вимірювання на реальному автоматі показали, що Ready інвертований (12 В означає «не готовий») і означає «приймання кредиту дозволене», а не «готує напій» — тому він блокує й на максимальному кредиті автомата. Команда просто чекає в черзі: у тесті одна простояла хвилини й нарахувалась, щойно автомат став готовий, без повтору
Оплата — це кредит, а не видача Автомат приймає кредит, а напій покупець обирає сам, тому на наліпках суми, а не назви напоїв — один QR на ціну замість одного на рецепт
Запуск через фото та покази мультиметра власника Розпіновку роз’єму J4 з’ясували дистанційно: фото плати, безпечна процедура щупання й перевірка полярності по одному контакту

Що передано

  • Worker і прошивка ESP32 з 18 автоматичними тестами: підроблені вебхуки, невідповідні суми, повтори, порядок, адмін-захист і спливання.
  • Панель у телефоні з живою телеметрією; автомат вважається офлайн після 120 секунд тиші.
  • Прошивальник у браузері, який віддає Worker, щоб власник прошив ESP32, нічого не встановлюючи.
  • Генератор друкованих аркушів із QR-наліпками (A4), ціни він читає з Worker.
  • Інструкція для замовника (PDF, docx та ODT): запуск, зміна цін і додавання ще одного автомата.
  • Набір CLI-утиліт: діагностика, симулятор оплати, що нічого не списує, тестова видача, термінальний емулятор ESP32, деплой і пакування релізу.

Близько 1 750 рядків JavaScript і C++, 42 коміти, від першого коміту 25 вересня 2026.


Стек

ESP32 · C++ (Arduino) · Cloudflare Workers · Durable Objects (SQLite) · Monobank Acquiring API · HY-M158 / PC817 · Node.js · Wrangler · IoT · Rheavendors