150 lines
9.2 KiB
Markdown
150 lines
9.2 KiB
Markdown
# Kaspi POS Automation
|
||
|
||
Автоматизация платежей для POS-систем через Kaspi Pay API. Проект предоставляет серверное приложение и веб-интерфейс для создания счетов, генерации QR-кодов, просмотра истории транзакций и оформления возвратов.
|
||
|
||
## Архитектура
|
||
|
||
```
|
||
┌──────────────┐ ┌──────────────────┐ ┌──────────────────┐
|
||
│ Web UI │◄─────►│ Express Server │◄─────►│ Kaspi Pay API │
|
||
│ (public/) │ │ (server.js) │ │ (entrance/ │
|
||
│ │ │ │ │ mtoken/qrpay) │
|
||
└──────────────┘ └──────────────────┘ └──────────────────┘
|
||
│
|
||
┌─────────┴─────────┐
|
||
│ src/ │
|
||
│ ├─ config.js │ Keypair, device, constants
|
||
│ ├─ crypto.js │ ECDH, ECDSA, TOTP, AES
|
||
│ ├─ helpers.js │ Fetch wrapper, headers
|
||
│ ├─ session.js │ Stateless session factory
|
||
│ ├─ logger.js │ File & console logging
|
||
│ ├─ polling.js │ Payment status polling
|
||
│ ├─ webhookStore │ Webhook management
|
||
│ └─ routes/ │ API route handlers
|
||
│ ├─ auth.js │ SMS auth (3-step)
|
||
│ ├─ invoice.js │ Invoice creation
|
||
│ ├─ qr.js │ QR code generation
|
||
│ ├─ history.js │ Transaction history
|
||
│ ├─ refund.js │ Refund processing
|
||
│ └─ session.js │ Session management
|
||
└───────────────────┘
|
||
```
|
||
|
||
Сервер **stateless после авторизации** — данные сессии (зашифрованный `vtokenSecret`, `tokenSN`, `profileId`) хранятся на стороне клиента и передаются через заголовки.
|
||
|
||
### Webhooks
|
||
|
||
Сервер автоматически отслеживает статусы созданных QR- и invoice-платежей (polling каждые 3 сек.) и отправляет HTTP POST-уведомления на указанные URL при изменении статуса.
|
||
|
||
- 📡 **События:** `payment.success` · `payment.failed` · `payment.expired`
|
||
- ⚙️ **Настройка:** файл `webhooks.json` (см. [`webhooks.example.json`](./webhooks.example.json))
|
||
- 🔐 **Подпись:** HMAC SHA-256
|
||
- 🔄 **Retry:** до 3 попыток с нарастающей задержкой
|
||
|
||
> 📖 Подробнее — в [документации API](./docs/API.md#webhooks--уведомления).
|
||
|
||
## Требования
|
||
|
||
- Node.js ≥ 20.6
|
||
|
||
## Быстрый старт
|
||
|
||
```bash
|
||
# 1. Клонировать репозиторий
|
||
git clone https://github.com/tapter-dev/kaspi-pos-automation.git
|
||
cd kaspi-pos-automation
|
||
|
||
# 2. Установить зависимости
|
||
npm install
|
||
|
||
# 3. Создать .env с ключом шифрования
|
||
echo "TOKEN_SECRET_KEY=$(openssl rand -hex 32)" > .env
|
||
|
||
# 4. (Опционально) Настроить вебхуки
|
||
cp webhooks.example.json webhooks.json
|
||
# Отредактируйте webhooks.json под свои нужды
|
||
|
||
# 5. Запустить сервер
|
||
npm start
|
||
```
|
||
|
||
При первом запуске автоматически генерируются `keypair.json` и `device.json`.
|
||
|
||
## Переменные окружения
|
||
|
||
| Переменная | Описание | По умолчанию | Обязательная |
|
||
| ------------------ | ---------------------------------------- | -------------------------- | ------------ |
|
||
| `TOKEN_SECRET_KEY` | 64-символьная hex-строка для AES-256-GCM | — | Да |
|
||
| `PORT` | Порт сервера | `3000` | Нет |
|
||
| `APP_VERSION` | Версия приложения Kaspi Pay | `4.110.1` | Нет |
|
||
| `APP_BUILD` | Номер сборки | `1099` | Нет |
|
||
| `APP_PLATFORM` | Платформа устройства | `iOS` | Нет |
|
||
| `APP_PLATFORM_VER` | Версия ОС | `18.5` | Нет |
|
||
| `APP_LOCALE` | Локаль | `ru-RU` | Нет |
|
||
| `APP_MODEL` | Модель устройства | `iPhone17,3` | Нет |
|
||
| `APP_BRAND` | Бренд устройства | `Apple` | Нет |
|
||
| `APP_DEVICE_NAME` | Имя устройства | `iPhone` | Нет |
|
||
| `APP_SCREEN_W` | Ширина экрана | `393.0` | Нет |
|
||
| `APP_SCREEN_H` | Высота экрана | `852.0` | Нет |
|
||
| `APP_CFNETWORK` | Версия CFNetwork | `CFNetwork/3826.500.131` | Нет |
|
||
| `APP_DARWIN` | Версия Darwin | `Darwin/24.5.0` | Нет |
|
||
|
||
> ⚠️ Параметры `APP_*` соответствуют реальному клиенту Kaspi Pay. API Kaspi валидирует эти значения и может отклонить запросы с неизвестными параметрами. Обновляйте их при выходе новой версии приложения.
|
||
|
||
## Ротация ключей
|
||
|
||
```bash
|
||
npm run regen:keypair # Перегенерация ECDSA-ключей
|
||
npm run regen:device # Перегенерация идентификатора устройства
|
||
```
|
||
|
||
Старые файлы сохраняются как `.bak`. После ротации существующие сессии становятся недействительными.
|
||
|
||
## Демо-интерфейс (`public/`)
|
||
|
||
В папке `public/` находится встроенный веб-интерфейс (SPA), который запускается автоматически вместе с сервером и доступен по адресу `http://localhost:3000`.
|
||
|
||
**Возможности интерфейса:**
|
||
|
||
- 🔐 **Авторизация** — вход по номеру телефона кассира Kaspi Pay через 3-шаговый SMS-flow (ввод номера → OTP-код → завершение)
|
||
- 🧾 **Выставление счёта** — создание счёта по номеру телефона клиента с указанием суммы и комментария
|
||
- 📱 **QR-оплата** — генерация QR-кода для оплаты с отслеживанием статуса в реальном времени
|
||
- 📋 **История операций** — просмотр списка транзакций с детализацией
|
||
- 💰 **Продажи и возвраты** — статистика продаж и оформление возвратов
|
||
|
||
**Файлы:**
|
||
|
||
| Файл | Описание |
|
||
| --- | --- |
|
||
| `public/index.html` | HTML-разметка и стили интерфейса |
|
||
| `public/app.js` | Клиентская логика (API-вызовы, управление состоянием) |
|
||
|
||
> Интерфейс предназначен для демонстрации и тестирования API. Для продакшена рекомендуется использовать собственный фронтенд.
|
||
|
||
## API документация
|
||
|
||
Подробная документация по всем эндпоинтам API: [`docs/API.md`](./docs/API.md).
|
||
|
||
📗 Документация также доступна на казахском языке: [`README.kk.md`](./README.kk.md) | [`docs/API.kk.md`](./docs/API.kk.md)
|
||
|
||
## Разработка
|
||
|
||
```bash
|
||
# Линтинг
|
||
npm run lint
|
||
|
||
# Форматирование
|
||
npm run format
|
||
|
||
# Тесты
|
||
npm test
|
||
```
|
||
|
||
## Лицензия
|
||
|
||
Этот проект распространяется под лицензией [MIT](./LICENSE).
|
||
|
||
## Участие в проекте
|
||
|
||
Мы приветствуем вклад сообщества! Пожалуйста, ознакомьтесь с [CONTRIBUTING.md](./CONTRIBUTING.md) перед созданием pull request.
|