# Оформление заказа — учебная спецификация

Учебная система «Интернет-магазин». Пример описания, которое аналитик может вести в SAQA. Приведённые API и бизнес-правила относятся к этому примеру, а не к API самой платформы SAQA.

## 1. Цель и границы

Покупатель создаёт заказ, получает ссылку на оплату и видит результат оплаты. Доставка запускается только после подтверждённого платежа.

В границах: создание заказа, проверка состава корзины, ожидание оплаты, подтверждение или отказ. Вне границ: возвраты, частичные платежи, скидки, резервирование остатков и расчёт доставки.

## 2. Участники и компоненты

| Компонент | Ответственность |
|---|---|
| Витрина / Web-приложение | Передать корзину и показать результат покупателю |
| Заказы / Order API | Проверить запрос, создать заказ и хранить его состояние |
| Каталог / Catalog API | Вернуть доступность и текущую цену товара |
| Оплата / Payment API | Создать платёжную попытку и сообщить её результат |
| Доставка / Delivery API | Принять оплаченный заказ в доставку |
| Уведомления / Notification API | Отправить подтверждение после успешной оплаты |

## 3. Основной сценарий

1. Витрина отправляет customer_id и непустой список items в Order API.
2. Order API проверяет количество и наличие товара через Catalog API. Стоимость считается на сервере, не берётся из запроса покупателя.
3. Order API создаёт заказ со статусом pending_payment.
4. Payment API создаёт платёжную попытку и возвращает ссылку на оплату.
5. Покупатель завершает оплату; результат приходит отдельным подтверждением от Payment API.
6. При подтверждённом успешном платеже заказ переходит в paid.
7. Order API передаёт заказ в Delivery API и отправляет событие для Notification API.

## 4. Альтернативные сценарии

| Условие | Ожидаемое поведение |
|---|---|
| Пустая корзина или quantity <= 0 | 400, заказ не создаётся |
| Товара нет в наличии | 409, заказ не создаётся |
| Платёж отклонён | Заказ остаётся pending_payment, доставка и подтверждение не запускаются |
| Повторён тот же запрос с тем же Idempotency-Key и телом | Возвращается исходный заказ, второй заказ не создаётся |
| С тем же Idempotency-Key передано другое тело | 409, исходный заказ не изменяется |
| Повторно пришло одно и то же подтверждение оплаты | Заказ остаётся paid; повторные доставка и уведомление не создаются |

## 5. HTTP-контракт создания

Метод: POST. Учебный адрес: https://api.example.com/orders.

Заголовки:
- Content-Type: application/json
- Idempotency-Key: checkout-demo-001

Тело:
```json
{
  "customer_id": "customer-001",
  "items": [{ "sku": "SKU-042", "quantity": 2 }]
}
```

Успешное создание: 201.
```json
{
  "order_id": "ord-001",
  "status": "pending_payment",
  "total_minor": 398000,
  "currency": "RUB",
  "payment_url": "https://payments.example.com/attempt/pay-001"
}
```

В этом примере total_minor — целое количество копеек. Цена товара и итоговая сумма определяются учебным Catalog API. 201 означает создание заказа, не успешную оплату.

## 6. Данные

- orders: идентификатор, customer_id, статус, итоговая сумма, валюта, ключ идемпотентности, хеш тела запроса.
- order_items: идентификатор строки, заказ, SKU, количество, цена на момент заказа.
- payment_attempts: идентификатор попытки, заказ, статус, идентификатор подтверждения от провайдера.

Учебная SQL-схема в checkout-schema.sql содержит структуру и ключи. Это модель данных для обсуждения, не готовая миграция и не полная реализация бизнес-правил.

## 7. Критерии приёмки

- [ ] Корректная корзина создаёт один заказ pending_payment и возвращает payment_url.
- [ ] Невалидный запрос не создаёт записи заказа.
- [ ] Повтор запроса не создаёт второй заказ.
- [ ] Отказ в оплате не запускает доставку.
- [ ] Успешное подтверждение переводит заказ в paid.
- [ ] Повторное подтверждение не повторяет доставку и уведомление.
- [ ] Сумма совпадает с ценами каталога на момент создания заказа.

## 8. Вопросы для согласования

- Как долго действует ссылка на оплату?
- Что делать с заказом, если подтверждение оплаты потерялось?
- Как согласованы таймауты, повторные вызовы и ошибки внешних сервисов?
- Как хранится ключ идемпотентности и как долго он действует?
- Нужна ли отдельная очередь для доставки и уведомлений?

Неопределённые условия нужно согласовать, прежде чем считать спецификацию готовой к реализации.
