Огляд
Платіжний контролер, який дає комерційному кавовому автомату 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 підтверджує виконання, і команда зникає з черги. Ідентифікатор останньої транзакції зберігається в енергонезалежній пам’яті, тож повтор ніколи не зарахує двічі |
Архітектура

Апаратна частина на один автомат — 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