Как мы создали Open-Source альтернативу закрытым платёжным системам на React, Node.js и WebNFC
Представьте парк аттракционов, фуд-корт на фестивале, корпоративную столовую или сеть автомоек. Что их объединяет? Всем им нужна своя закрытая платёжная система или внутренняя программа лояльности (клубные карты).
Обычно внедрение такой системы — это боль. Нужно покупать дорогие терминалы, нанимать интеграторов и пилить самописный софт. А что делать, если система нужна «на один раз» (для трёхдневного фестиваля) или у малого бизнеса просто нет бюджета?
Меня зовут Никита, и я решил закрыть эту боль, заодно прокачав своё портфолио. Я разработал легковесную, open-source альтернативу закрытым платёжкам, которая работает прямо в браузере, не требует скачивания приложений и сложного железа.
Под капотом — классический стек React + Node.js и капелька технологии в виде WebNFC.
🛠 Архитектура и технические костыли (с пользой для юзера)
Главная идея проекта — превратить любой обычный смартфон в платёжный терминал без установки лишнего софта. Всё работает через веб-приложение.
Основной упор был сделан на технологию WebNFC, которая позволяет считывать физические NFC-метки и карты прямо из браузера. Но тут мы сразу сталкиваемся с суровой реальностью: WebNFC сейчас поддерживается только в Chrome на Android.
if (!("NDEFReader" in window)) {
alert(
"Ошибка: Web NFC не поддерживается. Используйте Chrome на Android и HTTPS.",
);
return;
}
ndef.current = new NDEFReader();
ndef.current.onreading = async ({ message, serialNumber }) => {
if (readingLock.current) return;
setIsReading(true);
readingLock.current = true;
let cardObject = null;
try {
setUid(serialNumber);
for (const record of message.records) {
if (record.recordType !== "text") continue;
const decoder = new TextDecoder();
const textData = decoder.decode(record.data);
try {
cardObject = JSON.parse(textData);
setCardData(cardObject);
} catch {
console.log("Not JSON");
return;
}
console.log(
`UID: ${serialNumber} n Balance: ${cardObject.balance} n Name: ${cardObject.name}`,
);
addLog("read", serialNumber, cardObject.balance);
}
} catch (e) {
console.log("ошибка в карте", e);
} finally {
setIsReading(false);
readingLock.current = false;
}
};
Оставлять пользователей iOS за бортом было нельзя, поэтому я придумал элегантный фолбек:
-
Для Android: Терминал (смартфон администратора/кассира) считывает карту клиента в один клик через WebNFC по её уникальному идентификатору (UID).
-
Для iOS: На карте генерируется или печатается QR-код, содержащий тот же UID. Кассир просто сканирует его камерой внутри того же веб-приложения.

Как ходят данные:
На этапе MVP я не стал перегружать архитектуру тяжелыми СУБД, поэтому схема выглядит максимально лаконично:
Frontend (React) — отправляет UID карты и сумму —> Backend (Node.js) — парсит данные и проводит транзакцию —> JSON DB (быстрое файловое хранилище на первое время).

💼 В чём профит для бизнеса?
Зачем владельцу условной автомойки или кофейни внедрять такое решение вместо обычного банковского эквайринга? Я выделил 5 главных причин:
-
Деньги сразу в обороте. Клиент покупает локальную валюту или абонемент заранее. Деньги уже у вас в кассе, а услугу вы окажете потом. Это гарантирует, что клиент вернётся именно к вам, а не к конкурентам.
-
Психология «виртуальных денег». Тратить внутренние баллы или баланс с клубной карты психологически гораздо проще, чем расставаться с реальными рублями на балансе банка. Это кратно поднимает средний чек.
-
Прощай, грабительский эквайринг. Меньше транзакций через банк — меньше комиссий платежным системам. Бизнес экономит на каждом чихе.
-
Доступность «из коробки». Не нужно покупать терминалы за десятки тысяч рублей и оплачивать лицензии на софт. Нужен только копеечный набор NFC-карт (или распечатанных QR-кодов) и любой смартфон.
-
Прозрачный контроль. В систему встроен удобный лог для отслеживания всех операций с возможностью моментального экспорта в Excel для бухгалтерии.

🚀 Что дальше и где посмотреть код?
Получилась гибкая open-source система, которую можно развернуть за полчаса и адаптировать под задачи конкретного локального бизнеса или мероприятия.
В планах — прикрутить полноценную базу данных (MongoDB) вместо JSON-файлов, расширить ролевую модель (суперадмин, кассир, клиент) и добавить более красивую аналитику в реальном времени.
Проект полностью открытый. Вы можете изучить исходники, развернуть его у себя, закинуть пул-реквест или просто поставить звёздочку моему репозиторию.
👉 Ссылка на мой GitHub: https://github.com/lqdope/NFCwebPay/
Буду рад фидбеку в комментариях: взлетит ли такая альтернатива «на коленке» для мелкого бизнеса или WebNFC в вебе — всё ещё слишком нестабильная история?
Автор: lqdope

