Case 02. Payment Processing Platform¶
Практикум · Связанная теория · Редакционный стандарт
Тип материала — практический архитектурный кейс. HYPOTHETICAL — все численные параметры, сценарий и схемы. INFERENCE — выбор и критерии. UNKNOWN — фактическая производительность и параметры, которые предстоит согласовать.
1. Business problem¶
Мерчант должен знать судьбу платежа после сетевого сбоя, а бухгалтерия должна объяснить каждое списание и расчёт.
2. Functional requirements¶
Поддержать authorize, capture, refund, webhook inbox, ledger posting, импорт settlement и сверку. Раздельно хранить attempt, PSP reference и accounting effect.
3. Non-functional requirements¶
Bounded API deadline, durable pending при ambiguous outcome, контролируемый retry budget и независимая reconciliation до close.
4. Assumptions и вопросы заказчику¶
Assumption — один PSP на attempt, несколько captures имеют разные identities. Спросить provider idempotency scope/expiry, lookup API, partial capture, cutoff, валюты, сроки chargeback и правила перехода на другого PSP. UNKNOWN — гарантии выбранного контракта PSP.
5. Оценка нагрузки и объёма данных¶
HYPOTHETICAL. Средняя скорость 900 events/s, пик 1800 events/s, payload mean/p95/p99 1200/2000/3400 B. Перцентили заданы отдельно для тестового профиля, среднее используется для объёма. Суточный профиль упрощён до постоянного среднего, накладные расходы протокола, индексов и WAL исключены.
| Метрика | Формула и подстановка | Результат |
|---|---|---|
| Объём событий | 900 × 86 400 | 77760000 событий/сутки |
| Сырые данные | 77760000 × 1200 B | 93.312 GB/сутки |
| Retention без сжатия | 93.312 GB × 14 суток | 1306.368 GB |
| Broker copies при RF=3 | 1306.368 GB × 3 | 3919.104 GB, из них 2612.736 GB дополнительные копии |
| Producer bandwidth, среднее | 900 × 1200 × 8 / 10⁶ | 8.64 Mbit/s |
| Producer bandwidth, пик | 1800 × 1200 × 8 / 10⁶ | 17.28 Mbit/s |
| Partitions при 30% headroom | max(ceil(1800 × 1,3 / 1 500), ceil(1800 × 1200 × 1,3 / 1 800 000)) | 2 partitions |
| Consumer parallelism | ceil(1800 × 1,3 / 1 500) | 2 workers на группу при принятой производительности |
| Backfill одних суток при 3× средней capacity и живом среднем потоке | (900 × 86 400) / (3 × 900 − 900) | 43 200 с = 12 ч |
GB и Mbit здесь десятичные. 1 500 events/s на partition/worker и 1,8 MB/s на partition — допущения теста. Для варианта без брокера строки RF/partitions относятся к альтернативному потоку или downstream outbox. RF не моделирует egress каждого consumer: добавьте по одной копии трафика на активную группу и репликационный трафик до RF−1 дополнительных копий. Пересчитайте отдельно при catch-up на пике, skew и p99 payload. Если capacity ≤ live rate, конечного времени восстановления нет.
Rate относится к событиям журнала, включая webhook и settlement, а не к платежам. Калибровать events/payment по трассировке. Для provider throughput дополнительно посчитать capture fraction, retry amplification и ограничение конкурентности.
6. Варианты архитектуры¶
A — синхронный API вызывает PSP внутри orchestration path с durable attempt. B — локальный intent и outbox, worker вызывает PSP, клиент читает pending/status.
7. Сравнение вариантов и выбор¶
Выбрать B для устойчивого восстановления, при необходимости дать короткое ожидание результата поверх status endpoint. A сокращает happy-path round trips, но клиент чаще видит неопределённый timeout и удерживает ресурсы.
8. Component / data-flow¶
Иллюстративная схема выбранного варианта.
flowchart LR
A["Merchant API"] --> B["Payment orchestrator"]
B --> C["Operation journal and outbox"]
C --> W["Outbox worker"]
W --> D["External PSP"]
D --> I["Webhook and settlement inbox"]
I --> C
9. Normal processing sequence¶
sequenceDiagram
participant A as Merchant API
participant B as Payment orchestrator
participant C as Operation journal and outbox
participant W as Outbox worker
participant D as External PSP
A->>B: Send identified input
B->>C: Commit attempt and stable provider key
C-->>B: Return durable pending or completed status
C->>W: Relay committed attempt
W->>D: Capture with stable provider key
D-->>W: Provider operation reference
W->>C: Record verified result
Команда создаёт attempt и stable PSP key в одном DB commit. Worker отправляет запрос и сохраняет outcome. Verified webhook может прийти раньше ответа, guarded transition объединяет evidence. Ledger постит только по утверждённой accounting policy.
10. Failure / recovery sequence¶
sequenceDiagram
participant B as Outbox worker
participant C as External PSP
participant J as Operation journal
participant O as Recovery owner
B->>C: Capture with stable provider key
Note over B,C: Provider commits but network ACK is lost
O->>C: Look up same operation and reconcile
C-->>O: Durable outcome or explicit gap
O->>J: Resolve attempt or retain pending state
Если PSP подтвердил capture, но ACK потерян, попытка остаётся pending. Lookup по прежнему reference или повтор старого ключа в допустимом окне. После истечения окна — review и settlement evidence. Локальный lost commit ACK разрешить на authoritative writer по operation key.
11. Data model и contracts¶
Payment intent, attempt ID, scoped idempotency key, canonical fingerprint, provider operation ID, amount_minor и currency. Webhook transport ID дедуплицирует доставку, semantic ID защищает финансовое действие.
12. Consistency boundaries¶
Intent/outbox атомарны локально. Вызов PSP и database commit независимы. Inbox и guarded transition объединены. Journal фиксируется с accounting operation ID и balanced legs.
13. Scaling и capacity planning¶
Разделить queues по PSP и классу операции, cap concurrency на provider scope, backoff с jitter. При hot merchant сохранять порядок внутри payment aggregate, а не всей организации.
14. Observability¶
Возраст pending, unknown outcomes, webhook signature failures, PSP retries, orphan captures, settlement mismatch и lag outbox.
15. Data Quality и reconciliation¶
Сверить capture gross, refunds, fees, net, currency и bank movement. Найти missing/extra IDs, даже если net totals совпадают. Исключения получают owner и due date.
16. Security и compliance¶
Проверять подпись raw webhook и timestamp policy. Секреты не попадают в logs. PCI scope и retention согласуются для выбранного PSP и рынка.
17. Implementation roadmap¶
Сначала state machine и fixtures, затем sandbox PSP с fault injection, потом reconciliation и ограниченный production rollout.
18. Testing и acceptance criteria¶
Имитировать ACK loss до и после обоих commits, одинаковый ключ с другим payload, webhook reorder и duplicate, partial capture. Критерий — один accounting effect, корректный terminal/pending status и explainable settlement bridge.
19. Trade-offs и ограничения¶
Async путь даёт больше pending UI, зато упрощает recovery. PSP lookup недоступен при outage. Новый provider attempt допускается только после разрешения риска прежнего эффекта.
20. Interview questions¶
Почему HTTP 200 не доказывает settlement? API outcome имеет свою область, cash подтверждается отчётами и выпиской. Зачем хранить fingerprint? Повтор ключа с изменённой суммой должен вызвать конфликт, иначе клиент получит ответ о другой операции.
Первичные источники¶
Проверка источников: 2026-11-03. Документация описывает свойства компонентов. Результаты испытаний выбранной системы требуют отдельного evidence.