- Реализация платежной страницы с единственным методом оплаты — банковская карта
- Поддержка платёжных систем: Visa, Mastercard, Мир
- Возможность кастомизации платежной и успешной страниц
- Поддержка кастомных плагинов (например, OTP-верификация, поддержка просроченных карт)
- Адаптивный дизайн
- Защита от перебора ID
- Документация бизнес-логики через Swagger
- Технологии:
Vanilla JS,EJS + SSR,TailwindCSS - Почему SSR вместо CSR?
Для рендеринга кастомизированных шаблонов и стилей SSR оказался более уместным. CSR применим только к динамическому контенту, тогда как в этом проекте важно отдавать статически сгенерированные страницы в зависимости от конфигурации партнёра.
- Технологии:
Express,Zod,EJS,Swagger
- СУБД: PostgreSQL
- ORM: Drizzle
- Схема БД:
src/db/schema.js - Сиды:
src/db/scripts/seed.js
Для просмотра таблиц БД используйте npm run db:studio
-
Номер карты
- Проверка типа карты, длины и алгоритма Луна (Клиент получает конфигурацию платежных карт от сервера, исходя из этих данных происходит валидация)
- Файл:
/public/js/validators/card-number-validator.js
-
Срок действия карты
- Не может быть в прошлом
- Файл:
/public/js/validators/expiry-date-validator.js
-
CVV
- Проверка длины
- Файл:
/public/js/validators/cvv-validator.js
- Имя торговца (партнёра) — в верхней части страницы
- Иконка платёжной системы — отображается до полного ввода номера карты, иконки приходят вместе с конфигурацией платежных карт
Поддерживаются два типа торговцев:
- Стандартный шаблон — без необходимости конфигурации
- Кастомный шаблон — c настраиваемым внешним видом
paymentPageLayout: {
splitView: false, // Разделённый layout (форма информации слева, оплата справа)
errorContainerPosition: 'bottom' // Позиция ошибок
}successPageLayout: {
showOrderDetails: false, // Показывать детали заказа
showPaymentDetails: false // Показывать детали платежа
}Поддерживаются подключаемые кастомные плагины:
- OTP-верификация - файл:
/public/js/plugins/otp-verification.js - Поддержка expired cards (например, разрешение оплатить картой
4111с просроченным сроком) - файл:/public/js/plugins/allow-expired-cards.js
Плагины подключаются через:
paymentPageScripts: ['/js/plugins/otp-verification.js']Отображает:
- Номер заказа
- Дата транзакции
- Детали заказа: описание
- Детали платежа: тип карты, последние 4 цифры
- Сумма оплаты
- Комиссия (если указана)
- Ссылка на сайт партнёра
POST /api/order— Создание заказаPOST /api/order/calculate-commission— Расчет комиссииPOST /api/order/proceed— Исполнение транзакцииGET /api/order/available-cards— Конфигурация платежных карт
- Используется zod для валидации входных данных
- Кастомные валидаторы для кредитных карт:
src/lib/credit-card
- Разрешённые карты — только из конфига:
constants/cards.constants.js - Комиссии:
- Visa — 1%
- Mastercard — фиксировано 10 единиц
- Мир — 1% + 10 единиц
- Поддерживаемые валюты —
USD,RUB
- Защита от перебора ID
Используются UUID, энтропия 122 бита — перебор невозможен в реальных условиях - Страница заказа после оплаты
При повторном заходе — отображается страница успешной оплаты
-
Клонировать репозиторий:
git clone https://github.com/lostxs/payment-form.git cd payment-form -
Установить зависимости:
npm install
-
Создать файл
.envи заполнить его:cp .env.example .env
-
Запустить контейнер с базой данных:
docker compose up -d
-
Выполнить миграции и сиды:
npm run db:push # или npm run db:generate npm run db:migrate npm run db:seed -
Запустить сервер:
npm run start
-
swagger документация:
http://localhost:4000/api-docs -
Платежная страница:
GET /order/:id -
Страница успешной оплаты:
GET /success?orderId=:id
- Имя: Partner 1
- Дизайн: стандартный
- Редирект: https://example.com
- Имя: Partner 2
- Дизайн: кастомный
- Редирект: https://example.com
Добавьте или измените запись в partnersTable, пример в src/db/scripts/seed.js:
{
defaultPaymentPage: false,
paymentPageLayout: {
splitView: true,
errorContainerPosition: 'top'
},
paymentPageScripts: [
'/js/plugins/otp-verification.js'
]
}