Ниже — практический свод рекомендаций и паттернов для проектирования платёжного API с гибкой маршрутизацией транзакций, правилами расчёта комиссий и сценариями обработки отказов (fallback). Постарался дать и архитектуру, и примеры правил/форматов, и операционные практики — чтобы вы могли взять это как чек-лист и основу для реализации.
Ключевые принципы (высокоуровнево)
- Разделение control plane и data plane:
- Control plane — управление правилами/конфигурацией (маршруты, комиссии, политики fallback), UI/approval, валидация, версия правил.
- Data plane — скоростная обработка транзакций по текущим правилам; минимальная логика, быстрое принятие решений.
- Модульность: Router, Fee Engine, Provider Adapters/Gateways, Fallback Manager, Ledger/Orchestrator и Decision Engine как независимые компоненты.
- Правила как отдельный артефакт: версия, тесты, симуляция, аудит.
- Идемпотентность, аудит и согласованность денег: внутреннее ledger-слой для фиксации intent и состояния сделки.
- Обработку отказов через workflow/оркестратор (Temporal, Cadence, Step Functions) и очередь (DLQ) для долгих ретраев / ручного вмешательства.
Архитектура (компоненты)
- API Gateway / Frontend — валидация, аутентификация, rate limiting, идемпотентность (Idempotency-Key).
- Transaction Orchestrator — инициирует транзакцию, управляет статусами, вызывает Decision Engine и Provider Adapters, логирует в ledger.
- Decision Engine / Policy Engine — применяет маршрутизационные и fee-правила (может быть OPA, Drools или собственный DSL).
- Provider Adapters — плагины для каждого acquirer/PSP/bank с нормированным интерфейсом, circuit breaker.
- Fallback Manager / Retry Worker — реализует стратегии fallback: быстрый синхронный try, асинхронный retry, DLQ, ручной review.
- Ledger / Reconciliation — внутренняя учётная система (инициалы, резервы, списания, возвраты).
- Control Plane UI / Rule Store — интерфейс для редактирования/версионирования/симуляции правил.
- Observability: tracing (OpenTelemetry), метрики, дашборды per-provider, per-route, per-merchant.
Декомпозиция логики маршрутизации и комиссий
- Отдельный слой правил (Rule Engine) — решения принимаются исходя из данных транзакции + контекста (merchant, BIN, amount, MCC, время, country, riskScore и т. д.).
- Правило = условие (predicates) + действие (route selection / fee formula / fallback instructions) + priority/weight + version.
- Поддержка нескольких типов действия:
- Выбор provider (primary + ordered list of fallback providers)
- Split (разделение по долям/процентам) — useful для A/B, сарвиса оптимизации стоимости
- Dynamic pricing (выбрать provider с минимальной ожидаемой стоимости)
- Fee Engine отдельный: применяет последовательность правил для расчёта комиссий (merchant fee, network fee, provider fee, tax, markup).
Примеры критериев маршрутизации
- BIN (диапазон), card type (debit/credit, scheme), currency, country (issuing/merchant), amount (limits), MCC, merchant preferences, risk score, provider SLA/latency, historical success rate, cost per tx, time of day, regulatory constraints (e.g., PSD2, local acquirer requirement).
- Правило может использовать комбинированную логику: if currency == EUR and amount > 1000 and risk < 0.5 choose ProviderA else ProviderB.
Пример JSON-формата правила маршрутизации (упрощённо)
{
"id": "route-2026-01",
"version": 5,
"priority": 100,
"conditions": {
"all": [
{"field": "currency", "op": "==", "value": "EUR"},
{"field": "amount", "op": ">", "value": 1000},
{"field": "merchant.tier", "op": "in", "value": ["premium","enterprise"]}
]
},
"action": {
"type": "select",
"primary": "acquirer_A",
"fallback": ["acquirer_B", "acquirer_C"],
"max_retries_per_provider": 1,
"timeout_ms": 20000
},
"metadata": {"created_by":"ops@...", "env":"prod"}
}
Пример JSON-формата правила расчёта комиссии
{
"id": "fee-visa-1",
"version": 3,
"priority": 50,
"conditions": {"field":"card.scheme","op":"==","value":"VISA"},
"action": {
"type": "calc",
"formula": "max(1.00, amount * 0.018) + provider_fee",
"provider_fee_field": "provider.flat_fee"
}
}
Правила могут быть выражены в DSL (expression tree) или в JavaScript/rego/Drools — важно: sandbox + тесты + симуляция прежде чем применять в проде.
Fallback (обработка отказов) — стратегии
- Синхронный fallback:
- Быстрый retry по тому же провайдеру (N times) с коротким backoff.
- Перенаправление на следующий provider в цепочке fallback (failover).
- Параллельный (hedging):
- Отправить запросы к нескольким провайдерам параллельно и принять первый успешный ответ. Полезно для снижения latency, но увеличивает cost/complexity.
- Асинхронный retry:
- Поместить задачу в очередь и пытаться позднее с экспоненциальным бэкоффом, лимитом попыток; если неудача — DLQ/ручная проверка.
- Compensating actions:
- Если charge прошёл частично, выполнить rollback/void/refund последовательностью, записать в ledger.
- Manual intervention:
- Перевести транзакцию на ручную проверку (например, AML/fraud) с UI для оператора.
- Degraded mode:
- Переключиться на режим с минимальными проверками/другой ценой для критических потоков.
Fallback-параметры в правилах
- retry_count, retry_strategy (fixed/exp/backoff), per_provider_retries, timeout per attempt, hedging boolean, max_total_latency_allowed, escalate_to_manual_after_ntries.
Идемпотентность и состояния транзакции
- Требования:
- Клиент передаёт Idempotency-Key (или используйте transaction_id). Сервер должен гарантировать, что одинаковые запросы не создадут дубликатов и вернут один и тот же результат/статус.
- Жизненный цикл транзакции:
- created -> authorized -> captured/settled -> succeeded / failed -> refunded/chargeback -> reconciled
- Ведите audit trail для каждого перехода; каждая попытка к провайдеру логируется как sub-event.
API-эндпоинты (рекомендации)
- POST /transactions — инициировать платеж (идемпотентно)
- GET /transactions/{id} — получить статус и history
- POST /transactions/{id}/simulate — прогнать через правила без исполнения (для UI тестов)
- GET /routes, POST /routes, PUT /routes/{id} — CRUD правил маршрутизации (control plane)
- GET /fees, POST /fees — CRUD правил комиссий
- GET /providers, POST /providers — управление provider adapters
- POST /reconcile — ручной/плановый запуск сверки
- GET /metrics/provider/{provider}/health — per-provider health
- Webhooks: /webhooks/transactions — нотификации о смене статуса
Ошибки и коды (стандартизировать)
- Используйте структурированные коды: например PAYMENT_*, ROUTING_*, PROVIDER_TIMEOUT, PROVIDER_DECLINE, FRAUD_REJECT, INSUFFICIENT_FUNDS, IDP_DUPLICATE.
- В ответе: code, message, retriable (bool), suggested_action (e.g., try_alternate_provider).
Требования по безопасности и соответствию
- PCI DSS (токенизация карт, минимум хранения PAN), TLS everywhere, KMS для ключей, PCI SAQ для сервисов, PII encryption at rest.
- OAuth2 / mTLS / signed webhooks для взаимодействия с PSP и клиентами.
- RBAC и approval workflow для изменений правил (production rule changes must be approved and audited).
Observability и метрики
- Метрики: success_rate per provider, latency distribution, cost per tx, failover_count, retries_count, fallback_invocations, revenue/fees.
- Tracing: пропускайте trace-id через все вызовы (OpenTelemetry).
- Логи: структурированные, с transaction_id, provider_id, rule_version.
- Alerting: drop in success rate, spike in fallback usage, provider health.
Тестирование и деплой правил
- Симулятор в UI: возможность загружать реальные транзакции и видеть как правило сработает.
- Unit tests + property tests для каждого rule.
- Canary/gradual rollouts для новых правил.
- Ability to rollback instantly (feature flag or rule switch).
- Versioning: rules should be immutable once published; changes create new versions.
Производительность и масштабирование
- Решайте routing synchronously but compute decisions fast — cache frequently used rule results (e.g., per-BIN routing).
- Полосы критичности: latency budget для sync authorizations (обычно <300-1000ms).
- Hystrix-like circuit breakers per provider; bulkhead isolation.
- Для high throughput: use event-driven async processing for non-blocking long retries.
Учёт и сверка (reconciliation)
- Внутренний ledger как источник истины: сначала записать intent/reservation, затем reconcile with provider statements.
- Регулярные batch comparison (provider settlement files vs ledger) с автоматической коррекцией/созданием тикетов.
- Reconciliation metadata (provider_tx_id, provider_fee, settlement_date).
Пример сценариев и рекомендации
- Сценарий: low-cost routing
- Decision Engine смотрит на predicted_cost = provider_cost + estimated_fees + latency_penalty и выбирает минимальный predicted_cost при success_rate > threshold.
- Сценарий: high-risk transaction
- Если risk_score > 0.8: route only to providers that support 3DS + send to manual review fallback.
- Сценарий: provider timeout
- Try provider A with 3s timeout, on timeout try B with 5s; if both fail — push to async queue and notify merchant.
Операционные практики
- Audit trail для всех изменений правил + who/when/why.
- Business approvals & staged rollout.
- Runbooks для common failure modes: provider outage, broad declines, reconciliation mismatch.
- Regular chaos testing (bring provider adapters down) to ensure fallback logic works.
- Monitor cost/fees leakage — detect if rules accidentally give free-routing.
Примеры контрольных вопросов при проектировании
- Какие критерии должны влиять на выбор провайдера? (cost / latency / success_rate / compliance / 3DS)
- Нужно ли поддерживать параллельные (hedged) requests?
- Сколько попыток ретрая и какой таймаут допустим в sync path?
- Как быстро можно изменить правила в продакшн? Какая проверка и откат?
- Как будет выглядеть reconciliation и кто исправляет расхождения?
Короткие рекомендации для старта (практическая дорожная карта)
1. Постройте простой Router + Provider Adapter + Ledger MVP. Идемпотентность и audit обязаны быть с самого начала.
2. Вынесите правила в конфиг-файлы/DB с версионированием. Добавьте симулятор правил.
3. Добавьте Fee Engine как отдельную службу.
4. Внедрите Fallback Manager с простыми стратегиями (retry+ordered fallback); позже добавьте hedging.
5. Подключите tracing/metrics и начните собирать success_rate per provider.
6. Внедрите control plane UI с approvals и тестами перед промо в прод.
7. Регулярно проводите нагрузочное тестирование и chaos тесты.
Если хотите, могу:
- нарисовать конкретную ER-модель/схему таблиц для ledger и правил;
- предложить полное JSON API и список ошибок;
- написать пример простого DSL для правил (на rego или JSON-expression) и пример реализации Decision Engine.
Скажите, что из этого важнее сейчас — архитектура, примеры правил или пример API с полной схемой — и я подготовлю конкретный шаблон.