← Назад к вопросам

Расскажи про свой опыт проектирования сервиса с нуля

1.2 Junior🔥 221 комментариев
#Архитектура систем#Опыт и проекты

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Опыт проектирования сервиса с нуля: Payment Gateway для e-commerce

Я хотел бы рассказать о реальном проекте, который я проектировал с нуля в 2022 году — Payment Gateway для e-commerce платформы. Это был greenfield проект, где я отвечал за архитектуру и анализ на всех этапах.

Контекст и требования

Бизнес-требования:

  • Обработка 50K+ платежей в день
  • Поддержка 15+ платёжных методов (карты, e-wallets, bank transfers)
  • PCI-DSS compliance (уровень 1)
  • Real-time операции с <500ms latency
  • Интеграция с существующей платформой (legacy monolith)
  • Fallback на альтернативные провайдеры в случае сбоя

Non-functional requirements:

  • Availability: 99.99% uptime
  • Scalability: горизонтальное масштабирование
  • Security: шифрование, audit trail, fraud detection
  • Auditability: все операции логируются для compliance

Фаза 1: Анализ и проектирование архитектуры

Шаг 1: Исследование текущей ситуации

  • Провел интервью с Product team, Finance, Engineering lead
  • Изучил существующие платёжные системы конкурентов
  • Проанализировал законодательство в каждой стране
  • Провел risk assessment

Шаг 2: Определение граничных условий

Пиковая нагрузка: 50K платежей/день = ~1 платёж/сек (в среднем)
Пик: утро европейского дня = ~10 платежей/сек

Латентность:
- Клиент платит → ответ за <1сек
- Backend обрабатывает платёж → Провайдер за <500ms

Течность:
- Payment success rate должна быть >98%
- Fallback к backup провайдеру за <5сек

Шаг 3: Архитектурные решения

Выбрал микросервисную архитектуру с явными причинами:

Monolith
├── Users & Auth
├── Products & Catalog
├── Payment Service ← новое
├── Notifications
└── Analytics

Прежде я рассмотрел:

  1. Встроить в монолит → Сложно масштабировать, высокий risk
  2. Отдельный микросервис → ✅ Выбрано. Причины:
    • Независимая scalability
    • Отдельная deployment
    • Изоляция PCI-DSS требований
    • Возможность менять провайдеров без изменения монолита

Фаза 2: Детальное проектирование

1. Core entities и data model

-- Payment request (от клиента)
CREATE TABLE payment_requests (
  id UUID PRIMARY KEY,
  order_id UUID NOT NULL,
  amount DECIMAL(12, 2) NOT NULL,
  currency VARCHAR(3) NOT NULL,
  payer_id UUID NOT NULL,
  payment_method_id UUID NOT NULL,
  status ENUM ('pending', 'processing', 'succeeded', 'failed', 'cancelled'),
  created_at TIMESTAMPTZ NOT NULL,
  expires_at TIMESTAMPTZ NOT NULL,
  UNIQUE(order_id)  -- One payment per order
);

-- Payment transaction (фактический платёж через провайдера)
CREATE TABLE payment_transactions (
  id UUID PRIMARY KEY,
  payment_request_id UUID NOT NULL REFERENCES payment_requests(id),
  provider_id SMALLINT NOT NULL,  -- Stripe, PayPal, etc
  provider_transaction_id VARCHAR(255) NOT NULL,
  status ENUM ('pending', 'succeeded', 'failed', 'declined'),
  amount DECIMAL(12, 2) NOT NULL,
  fee DECIMAL(12, 2) NOT NULL,  -- Комиссия провайдера
  retry_count SMALLINT DEFAULT 0,
  error_code VARCHAR(100),
  error_message TEXT,
  response_time_ms INT,
  created_at TIMESTAMPTZ NOT NULL,
  updated_at TIMESTAMPTZ NOT NULL,
  FOREIGN KEY (payment_request_id) REFERENCES payment_requests(id)
);

-- Audit log для compliance
CREATE TABLE payment_audit_log (
  id BIGSERIAL PRIMARY KEY,
  payment_request_id UUID NOT NULL,
  action VARCHAR(50) NOT NULL,  -- 'created', 'processing', 'succeeded', etc
  actor VARCHAR(100) NOT NULL,  -- 'system', 'user_id', 'provider'
  details JSONB,
  ip_address INET,
  user_agent TEXT,
  created_at TIMESTAMPTZ NOT NULL,
  INDEX (payment_request_id, created_at)
);

2. API контракты

Client → Load Balancer → Payment Service → Payment Processors

REST API endpoints:

1. POST /api/v1/payments
   Request: {
     "order_id": "uuid",
     "amount": 99.99,
     "currency": "USD",
     "payment_method_id": "uuid",
     "customer_id": "uuid"
   }
   Response: {
     "id": "uuid",
     "status": "processing",
     "redirect_url": "https://provider.com/verify?token=xxx"
   }
   Status: 201 Created

2. GET /api/v1/payments/{id}
   Response: {
     "id": "uuid",
     "status": "succeeded",
     "amount": 99.99,
     "provider": "stripe",
     "provider_transaction_id": "ch_xxx"
   }

3. POST /api/v1/payments/{id}/retry
   (Retry failed payment with fallback provider)

4. POST /api/v1/webhooks/stripe
   (Webhook от провайдера)

Фаза 3: Обработка платежей (Flow)

Синхронный flow (для быстрых провайдеров)

1. Client initiates payment
   ↓
2. Payment Service validates input
   ↓
3. Create payment_request with status='pending'
   ↓
4. Call Payment Provider (Stripe, PayPal)
   ↓
5. If success (< 500ms):
   - Update payment_request to 'succeeded'
   - Send notification
   - Return 200 OK
   
6. If timeout/error:
   - Try fallback provider
   - If fallback succeeds → same as 5
   - If all fail → status='failed', return 402 Payment Required

Асинхронный flow (для 3D Secure, redirects)

1. Client initiates payment
   ↓
2. Payment Service creates payment_request
   ↓
3. Generate redirect_url с verification token
   ↓
4. Client is redirected to provider (iframe или новый window)
   ↓
5. Client завершает 3D Secure
   ↓
6. Provider redirects back to us с callback
   ↓
7. Webhook handler обновляет status
   ↓
8. Client polling GET /payments/{id} → status='succeeded'

Фаза 4: Resilience и Fallback

Circuit breaker pattern:

# Если Stripe downtime > 1 минуты:
# - Все новые платежи идут на PayPal
# - Старые platежи retry автоматически

STRIPE_FAILURE_THRESHOLD = 5  # failures per minute
FAILURE_WINDOW = 60  # seconds

if stripe_failures_in_window > THRESHOLD:
    stripe_circuit_breaker.open()
    # Route all traffic to backup provider

Retry logic:

Первая попытка: Stripe
Если timeout → Вторая попытка: Stripe (exponential backoff)
Если всё ещё timeout → Третья попытка: PayPal

Максимум 3 попытки, максимум 30 секунд

Фаза 5: Security

PCI-DSS Compliance (Level 1)

  1. Никогда не храним credit card data — используем токены
  2. Вся коммуникация через HTTPS с TLS 1.2+
  3. Database encryption at rest (AES-256)
  4. Audit logging всех операций
  5. IP whitelisting для провайдеров
  6. Rate limiting (10 платежей в минуту per customer)
  7. Fraud detection (странная сумма, странная геолокация)

Пример fraud detection:

if (new_amount > customer.avg_payment * 10 and 
    customer.last_location != current_location and 
    time_since_last_payment < 5_minutes):
    
    flag_for_review = True
    send_verification_email(customer)

Фаза 6: Мониторинг и метрики

Ключевые метрики:

1. Success rate per provider
   - Stripe: 99.5%
   - PayPal: 99.2%

2. Latency percentiles
   - p50: 200ms
   - p95: 450ms
   - p99: 800ms

3. Error rates by code
   - declined_card: 2.5%
   - insufficient_funds: 0.8%
   - timeout: 0.1%

4. Revenue metrics
   - Total processed: $XXX
   - Failed payments: $YYY
   - Failed rate by geography

Мониторинг:

- Prometheus для метрик
- ELK для логов
- PagerDuty для алертов
- Grafana для dashboards

Алерты:
- Success rate < 95% → page on-call
- P99 latency > 2 sec → warning
- Circuit breaker trips → page on-call

Фаза 7: Развёртывание

Стратегия:

  1. Stage 1: Canary (1% трафика, real transactions, 2 недели)

    • Validate implementation
    • Monitor fraud rate
    • Adjust settings
  2. Stage 2: Gradual rollout (10% → 50% → 100%, 3 недели)

    • Run А/В тест (старая vs новая система)
    • Monitor success rate
    • Have instant rollback plan
  3. Stage 3: Full migration

    • Sunset старой платёжной системы
    • Archive старые данные

Результаты

После запуска:

  • ✅ Success rate: 99.3%
  • ✅ Latency p95: 380ms
  • ✅ Uptime: 99.98%
  • ✅ Zero PCI violations за 2 года
  • ✅ Обработано $500M+ через сервис
  • ✅ Team scales from 2 engineers to 6 (нужны ещё люди)

Ключевые уроки

  1. Start with non-functional requirements, not features
  2. Resilience first — платёжные системы не могут быть down
  3. Compliance drives architecture — PCI-DSS constraints are real
  4. Fallback is not optional — single provider is a single point of failure
  5. Monitoring is critical — you need to know in real-time if payments fail
  6. Test in production carefully — use canary deployments and feature flags

Этот опыт показал мне важность системного мышления и взаимодействия с разными stakeholders при проектировании критичных сервисов.

Расскажи про свой опыт проектирования сервиса с нуля | PrepBro