Клиентский API не должен ждать 2–5 секунд ответа платёжного шлюза и рисковать таймаутом. Нужно принять платёж мгновенно, обработать в фоне, уведомить клиента вебхуком и при этом не потерять и не задвоить ни один платёж.
API отвечает 202 Accepted, пишет платёж и событие в outbox одной транзакцией PostgreSQL. Фоновый publisher (FOR UPDATE SKIP LOCKED) переносит события в RabbitMQ. Consumer на FastStream вызывает шлюз, обновляет статус, шлёт вебхук с тремя повторами. Исчерпанные попытки уходят в DLQ. Повтор запроса с тем же Idempotency-Key возвращает тот же платёж.
Ни одно событие не теряется при падении брокера или сервиса: outbox гарантирует доставку. Два процесса (API и consumer) масштабируются независимо. Health и readiness эндпоинты, Docker Compose, тесты, документ по архитектуре. Те же паттерны применимы к любой интеграции с внешним API: уведомления, синхронизация с CRM, доставка в 1С.