Skip to content

reixxen/payment-form

Repository files navigation

Payment Form

Цель проекта

  • Реализация платежной страницы с единственным методом оплаты — банковская карта
  • Поддержка платёжных систем: Visa, Mastercard, Мир
  • Возможность кастомизации платежной и успешной страниц
  • Поддержка кастомных плагинов (например, OTP-верификация, поддержка просроченных карт)
  • Адаптивный дизайн
  • Защита от перебора ID
  • Документация бизнес-логики через Swagger

Архитектура приложения

1. Frontend

  • Технологии:
    Vanilla JS, EJS + SSR, TailwindCSS
  • Почему SSR вместо CSR?
    Для рендеринга кастомизированных шаблонов и стилей SSR оказался более уместным. CSR применим только к динамическому контенту, тогда как в этом проекте важно отдавать статически сгенерированные страницы в зависимости от конфигурации партнёра.

2. Backend

  • Технологии:
    Express, Zod, EJS, Swagger

3. База данных

  • СУБД: 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 цифры
  • Сумма оплаты
  • Комиссия (если указана)
  • Ссылка на сайт партнёра

Backend — API-эндпоинты

  • 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 бита — перебор невозможен в реальных условиях
  • Страница заказа после оплаты
    При повторном заходе — отображается страница успешной оплаты

Установка

  1. Клонировать репозиторий:

    git clone https://github.com/lostxs/payment-form.git
    cd payment-form
  2. Установить зависимости:

    npm install
  3. Создать файл .env и заполнить его:

    cp .env.example .env
  4. Запустить контейнер с базой данных:

    docker compose up -d
  5. Выполнить миграции и сиды:

    npm run db:push   # или npm run db:generate npm run db:migrate
    npm run db:seed
  6. Запустить сервер:

    npm run start

Использование

  • swagger документация:
    http://localhost:4000/api-docs

  • Платежная страница:
    GET /order/:id

  • Страница успешной оплаты:
    GET /success?orderId=:id


Примеры торговцев

Стандартный

Кастомный


Как кастомизировать

Добавьте или измените запись в partnersTable, пример в src/db/scripts/seed.js:

{
  defaultPaymentPage: false,
  paymentPageLayout: {
    splitView: true,
    errorContainerPosition: 'top'
  },
  paymentPageScripts: [
    '/js/plugins/otp-verification.js'
  ]
}

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors