Статус проекта: Pre-launch MVP (Q4 2025)

Строим B2B-платформу для международной торговли, где решаем сразу несколько болей:
Double-blind маркетплейс - контрагенты не видят друг друга → нет обхода площадки
RFQ + реверс-аукционы - быстрый сбор конкурентных предложений
DDP-калькулятор - прозрачная «цена под ключ» ещё до сделки
Новинка: платёжный клиринг - агрегируем встречные потоки экспорта/импорта и делаем две локальные выплаты (в РФ и за рубежом) через лицензированных провайдеров
⚠️ Важно: Платформа не банк и не платёжная система. Все реальные выплаты выполняются лицензированными операторами (банки/НКО/EMI). Мы — интерфейс и оркестратор.

Какую боль решаем
Проблема 1: Обход площадки
Как только покупатель и поставщик узнают друг друга, они уходят в прямой контакт. Площадка теряет комиссию, а стороны - страховку и гарантии.
Проблема 2: Непрозрачная итоговая цена
«Сколько это будет стоить с пошлинами, логистикой, брокером и последней милей?» - на этот вопрос отвечают обычно через неделю и три итерации писем.
Проблема 3: Дорогие кроссбордер-переводы
SWIFT-платежи: 2-5% комиссии, 3-7 дней, непредсказуемые конверсии и комплаенс -блокировки.
Проблема 4: Длинные цепочки посредников
Экспортёр → брокер → банк-корреспондент → ещё банк → импортёр. Каждый хочет свой кусок, каждый добавляет риск.
Архитектура решения
1. Double-blind маркетплейс + RFQ/Аукционы
flowchart LR
A[RFQ Creation] --> B[Reverse Auction]
B --> C[Deal Draft]
C --> D[Escrow/Payment]
D --> E[Shipment Leg1]
E --> F[Shipment Leg2]
F --> G[Settlement]
style B fill:#90EE90
style D fill:#FFD700
style G fill:#87CEEB
Как работает:
Покупатель создаёт RFQ (Request for Quotation)
Поставщики подают ставки в реверс-аукционе
В UI все видят только псевдонимы - double-blind
Для банков/таможни/регуляторов данные прозрачны
Результат: Обход площадки теряет смысл - контрагенты друг друга не знают.
2. DDP-калькулятор
Показываем оценочную цену «под ключ» ещё до подписания сделки:
{
"currency": "EUR",
"breakdown": {
"goods": 10000,
"export_fees": 100,
"intl_freight": 450,
"insurance": 35,
"import_duty": 500,
"import_vat": 2205,
"broker": 120,
"three_pl": 180,
"last_mile": 90,
"platform_fee": 200,
"psp_fee": 90
},
"total": 15870
}
Результат: Покупатель видит real cost, нет сюрпризов при доставке.
3. Эскроу через лицензированных провайдеров
Мы не храним и не переводим деньги. Это делают:
Банки-партнёры
НКО (небанковские кредитные организации)
EMI (electronic money institutions)
Платформа — интерфейс:
Показываем статусы
Сопоставляем документы
Уведомляем стороны
Триггерим выплаты по событиям (POD, таможня)
Новый модуль: платёжный клиринг с неттингом
Идея: Вместо дорогих кроссбордер-переводов делаем две локальные выплаты — в РФ и за рубежом.

Как это работает
flowchart TB
subgraph "Традиционная схема"
A1[Импортёр RU] -->|SWIFT $10k<br/>Комиссия ~3%| A2[Экспортёр TR]
B1[Экспортёр RU] -->|SWIFT $8k<br/>Комиссия ~3%| B2[Импортёр TR]
end
subgraph "Через клиринг"
C1[Импортёр RU] -->|Локально ₽| C3[Платформа RU]
C3 -->|Локально ₽| C2[Экспортёр RU]
D1[Экспортёр TR] -->|Локально ₺| D3[Платформа TR]
D3 -->|Локально ₺| D2[Импортёр TR]
end
style A1 fill:#FFB6C1
style B1 fill:#FFB6C1
style C3 fill:#90EE90
style D3 fill:#90EE90
Поток клиринговой заявки
Шаг 1: Создание инструкции
{
role: "importer" | "exporter",
payout_place: "ru" | "foreign",
corridor: "RU→TR",
currency: "EUR",
amount: 15870,
settlement_window: "T+0" | "T+1" | "T+2",
documents: File[] // инвойс, контракт
}
Шаг 2: Сведение заявок (matching)
Система находит встречные потоки
Double-blind в UI: стороны не видят друг друга
Провайдеры видят полную картину для комплаенса
Шаг 3: Исполнение
Локальная выплата в РФ (через российского провайдера)
Локальная выплата за рубежом (через зарубежного провайдера)
Статусы:
Queued → Matched → Paid_RU → Paid_Foreign → Settled
↓ (if no match)
Expired / Fallback to standard
Экономика
Метод |
Комиссия |
Срок |
Риски |
---|---|---|---|
SWIFT |
2-5% |
3-7 дней |
Блокировки, конверсия |
Crypto |
1-3% |
1-24 часа |
Волатильность, легальность |
Клиринг |
0.1-0.3% (bps) |
T+0 до T+2 |
Зависит от matching |
Volume tiers:
До $100k/месяц: 30 bps (0.3%)
$100k-$1M: 20 bps
$1M+: 10 bps
Технический стек
Frontend
// Реальная структура из проекта
{
"framework": "React 18.3 + TypeScript 5.8",
"build": "Vite 5.4",
"ui": "shadcn/ui (Radix) + Tailwind CSS",
"state": "React Query 5.83 + Zustand",
"forms": "react-hook-form + zod",
"routing": "React Router 6.30"
}
Backend
// backend/package.json (реальный)
{
"express": "^4.18.2",
"pg": "^8.11.0", // PostgreSQL
"redis": "^4.6.10", // Кэш + rate-limiting
"helmet": "^7.0.0", // Security headers
"jsonwebtoken": "^9.0.2", // Auth
"multer": "^1.4.5" // File uploads
}
Infrastructure
# docker-compose.prod.yml (фрагмент)
services:
frontend:
build: ./
ports: ["3000:80"]
backend:
build: ./backend
environment:
- NODE_ENV=production
- DATABASE_URL=${DATABASE_URL}
ports: ["3001:3000"]
nginx:
image: nginx:alpine
volumes:
- ./nginx-cloudflare.conf:/etc/nginx/nginx.conf
ports: ["80:80", "443:443"]
CDN/Security: Cloudflare
DNS + CDN (HTTP/3, Brotli)
WAF (Web Application Firewall)
Turnstile (антибот)
R2 (объектное хранилище)
Безопасность
1. Аутентификация
// Реализовано в проекте
- Supabase Auth с MFA (TOTP)
- HttpOnly cookies (планируется миграция с Supabase localStorage)
- Session invalidation в Redis
- Rate limiting на /auth endpoints
2. Headers (Nginx)
# nginx-cloudflare.conf (реальный конфиг)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
# CSP (сначала Report-Only, потом enforce)
add_header Content-Security-Policy-Report-Only "
default-src 'self';
img-src 'self' data: https:;
style-src 'self' 'unsafe-inline';
script-src 'self' https://challenges.cloudflare.com;
connect-src 'self' https: wss:;
frame-src https://challenges.cloudflare.com;
" always;
3. Cloudflare Turnstile
// backend/src/middleware/turnstile.js (планируется)
export async function verifyTurnstile(token, ip) {
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 3000);
try {
const response = await fetch(
'https://challenges.cloudflare.com/turnstile/v0/siteverify',
{
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
secret: process.env.TURNSTILE_SECRET_KEY,
response: token,
remoteip: ip
}),
signal: controller.signal
}
);
const data = await response.json();
return data.success;
} catch (error) {
console.error('Turnstile verification failed:', error);
return false;
} finally {
clearTimeout(timeout);
}
}
4. Identity Vault (в разработке)
// Концепт: envelope encryption
interface IdentityVault {
ciphertext: string; // Encrypted identity data
iv: string; // Initialization vector
tag: string; // Auth tag
keyId: string; // Reference to KEK in KMS
version: number; // For key rotation
}
// Шифрование
const dek = crypto.randomBytes(32); // AES-256
const { ciphertext, iv, tag } = aesGcmEncrypt(dek, JSON.stringify(identity));
const wrappedDek = kms.wrapKey(dek, keyId); // KEK в Vault/KMS
await db.identities.insert({ ciphertext, iv, tag, keyId, version: 1 });
Что уже работает ✅
Production Ready (v0.1.0)
[x] Регистрация + MFA (TOTP через Supabase)
[x] RFQ система (создание запросов)
[x] Офферы (подача предложений)
[x] Сделки (базовый документооборот)
[x] Калькуляторы (UI готов, бизнес-логика в процессе)
[x] Docker-compose деплой
[x] GitHub Actions CI/CD
[x] Cloudflare CDN + WAF
Скриншоты
Dashboard с RFQ:
┌─────────────────────────────────────────────────┐
│ ? Мои запросы (RFQ) │
├─────────────────────────────────────────────────┤
│ ID: RFQ-001 │ Товар: HS 481920 │ Статус: ⏳ │
│ Офферов: 3 │ Лучшая цена: €15k │ До: 2 дня │
├─────────────────────────────────────────────────┤
│ ID: RFQ-002 │ Товар: HS 392690 │ Статус: ✅ │
│ Офферов: 5 │ Выбран: €8.5k │ В работе │
└─────────────────────────────────────────────────┘
Форма клиринговой инструкции (макет):
<Card>
<CardHeader>
<CardTitle>Инструкция на клиринг</CardTitle>
</CardHeader>
<CardContent>
<Form {...form}>
<RadioGroup name="role">
<Label>Импортёр</Label>
<Label>Экспортёр</Label>
</RadioGroup>
<Select name="corridor">
<option>RU → TR</option>
<option>RU → AE</option>
</Select>
<Input name="amount" type="number" />
<Select name="settlement_window">
<option>T+0 (сегодня)</option>
<option>T+1 (завтра)</option>
</Select>
<FileUpload accept=".pdf" maxFiles={5} />
<Turnstile sitekey={SITE_KEY} />
<Button type="submit">Создать</Button>
</Form>
</CardContent>
</Card>
Roadmap
Q4 2025 - Closed Beta ⏳
[ ] Модуль клиринга: UI + API
[ ] Подключение 2 коридоров (RU↔TR, RU↔AE)
[ ] Интеграция 1-2 лицензированных провайдеров
[ ] WebSocket для real-time статусов
[ ] Cloudflare Turnstile на всех формах
[ ] Smart Договора
Q1 2026 - MVP Launch
[ ] Расширение до 5+ коридоров
[ ] Volume tiers для комиссий
[ ] DDP-калькулятор с реальными API тарифов
[ ] Identity Vault (envelope encryption)
[ ] Экспорт отчётов для бухгалтерии
Q2-Q4 2026 - Scale
[ ] Реверс-аукционы с WebSocket
[ ] Интеграция 3PL/брокеров по API
[ ] ML-рекомендации по коридорам
[ ] Multi-currency settlements
[ ] Mobile app (PWA → native)
2027+ - Enterprise
[ ] ERP интеграции (SAP, 1C)
[ ] White-label решения
[ ] Собственная лицензия НКО (опционально)
API Примеры
Создать клиринговую инструкцию
POST /api/clearing/instructions
Content-Type: multipart/form-data
{
"role": "importer",
"payout_place": "foreign",
"corridor": "RU->TR",
"currency": "EUR",
"amount": 15870,
"settlement_window": "T+1",
"documents": [File, File],
"turnstileToken": "0x..."
}
Response 201:
{
"data": {
"id": "clrn_abc123",
"status": "queued",
"eta": "2025-10-06T12:00:00Z"
}
}
Получить статус
GET /api/clearing/instructions/clrn_abc123
Response 200:
{
"data": {
"id": "clrn_abc123",
"status": "settled",
"timeline": [
{ "at": "2025-10-05T10:12:00Z", "status": "queued" },
{ "at": "2025-10-05T11:03:00Z", "status": "matched" },
{ "at": "2025-10-05T11:45:00Z", "status": "paid_ru" },
{ "at": "2025-10-05T12:10:00Z", "status": "paid_foreign" }
]
}
}
FAQ
Q: Вы банк?
A: Нет. Мы интерфейс/агент. Все выплаты через лицензированных провайдеров (банки/НКО/EMI).
Q: Что если нет встречной заявки?
A: Заявка остаётся в очереди. Можно изменить окно/сумму или выбрать стандартный перевод через провайдера.
Q: Почему не криптовалюта?
A: 1) Легальные риски в РФ, 2) Волатильность, 3) B2B требует fiat-расчётов для бухгалтерии. Но можем добавить опционально.
Q: Сколько стоит пилот?
A: Базовый пилот (1-2 коридора, до 50 сделок/месяц) — от €50k.
Lessons Learned ?
✅ Правильные решения
1. Supabase вместо самописного auth
Сэкономили ~2 месяца. MFA, RLS, Storage — из коробки.
2. shadcn/ui вместо готовой UI-библиотеки
Полный контроль над компонентами. Легко кастомизировать.
3. Docker-compose для деплоя
Один файл — весь стек. Rollback за 30 секунд.
⚠️ Что переделывали
1. localStorage → HttpOnly cookies (в планах)
Supabase по умолчанию хранит JWT в localStorage. XSS-риски.
Планируем custom auth с HttpOnly cookies.
2. Монолит → Микросервисы (будущее)
Сейчас всё в одном Express app.
При росте разделим: API Gateway, Auth Service, WebSocket Server.
3. Mock данные → Real API
DDP-калькулятор работает на hardcoded ставках.
Подключаем API таможенных тарифов.
? Главные боли
WebSocket в production
Socket.IO требует sticky sessions или Redis adapter.
Отложили до завершения MVP.
GDPR compliance
Юридические аспекты "права на забвение" сложнее технических.
Наняли внешнего консультанта.
Rate limiting в кластере
Express-rate-limit держит счётчики в памяти.
Переходим на Redis для shared state.
Дисклеймер ?
Этот материал описывает прототип и возможную модель.
Любые реальные выплаты выполняются только лицензированными провайдерами (банки/НКО/EMI) по отдельным договорам и в рамках действующего права.
Платформа не принимает и не переводит средства. Мы — интерфейс и оркестратор.
Контакты
Попробовать демо:
? По запросу
Обсудить пилот:
? amonoc@yandex.ru
? Telegram: @amonoc
Для интеграторов/партнёров:
Если вы 3PL/брокер/PSP/банк — давайте обсудим API-интеграцию.
Глоссарий
RFQ (Request for Quotation) - запрос коммерческого предложения
Double-blind - контрагенты не видят друг друга в UI
DDP (Delivered Duty Paid) - цена «под ключ» с доставкой и пошлинами
Клиринг/неттинг - взаимозачёт встречных обязательств
bps (basis points) - сотые доли процента (1 bps = 0.01%)
T+0/T+1/T+2 - день расчёта (сегодня/завтра/послезавтра)
Leg1/Leg2 - первое/второе плечо логистики