Процесс покупки в интернет-магазине
Полный путь клиента от обнаружения товара до доставки и послепродажной поддержки.
Обзор
Процесс покупки включает:
- Обнаружение товара (просмотр, поиск, фильтрация)
- Детали товара и отзывы
- Управление корзиной
- Процесс оформления заказа (доставка, оплата)
- Подтверждение заказа и отслеживание
- Доставка и послепродажные действия
Основная диаграмма процесса
Детали этапов
1. Обнаружение товара
Эндпоинт просмотра: GET /products
Параметры запроса:
| Параметр | Тип | Описание |
|---|---|---|
| category | string | Slug категории |
| minPrice | number | Фильтр минимальной цены |
| maxPrice | number | Фильтр максимальной цены |
| sort | string | popular, newest, price_asc, price_desc |
| page | number | Номер страницы (по умолчанию: 1) |
| limit | number | Товаров на страницу (по умолчанию: 20, максимум: 100) |
| inStock | boolean | Показывать только товары в наличии |
Эндпоинт поиска: GET /products/search
Параметры запроса:
| Параметр | Тип | Описание |
|---|---|---|
| q | string | Поисковый запрос (минимум 2 символа) |
| category | string | Опциональный фильтр категории |
| sort | string | relevance, popular, price_asc, price_desc |
Реализация поиска:
- Полнотекстовый поиск PostgreSQL с tsvector
- Взвешенный поиск: название (A), описание (B), SKU (C)
- Нечеткое сопоставление для толерантности к опечаткам
2. Детали товара
Эндпоинт: GET /products/{slug}
Ответ:
{
"id": "uuid",
"sku": "WH-BT-001",
"name": "Wireless Headphones Pro",
"slug": "wireless-headphones-pro",
"shortDescription": "Premium wireless headphones with noise cancellation",
"description": "Full HTML description...",
"basePrice": 9990.00,
"salePrice": 7990.00,
"currency": "RUB",
"status": "ACTIVE",
"stockQuantity": 45,
"inStock": true,
"images": [
{ "url": "https://cdn.../main.jpg", "isPrimary": true },
{ "url": "https://cdn.../side.jpg", "isPrimary": false }
],
"category": {
"id": "uuid",
"name": "Electronics",
"slug": "electronics"
},
"reviewsSummary": {
"averageRating": 4.5,
"totalReviews": 128
},
"careerPointsValue": 100.00
}Отображение статуса наличия:
| Уровень наличия | Отображение |
|---|---|
| > 10 | "В наличии" |
| 1-10 | "Осталось только X" |
| 0 | "Нет в наличии" |
3. Добавление в корзину
Эндпоинт: POST /cart/items
Запрос:
{
"productId": "product-uuid",
"quantity": 2
}Правила валидации:
| Правило | Ограничение |
|---|---|
| Количество | Минимум: 1, Максимум: 99 |
| Наличие | quantity <= доступный запас |
| Статус товара | Должен быть ACTIVE |
| Товаров в корзине | Максимум 50 уникальных товаров |
Идентификация корзины:
- Авторизованный: По user_id
- Гость: По session_id (cookie)
Атрибуция реферала:
- Корзина наследует
referring_partner_idиз атрибуции сессии - Сохраняется, даже если пользователь входит во время оформления
4. Управление корзиной
Эндпоинт получения корзины: GET /cart
Ответ:
{
"id": "cart-uuid",
"items": [
{
"id": "item-uuid",
"product": {
"id": "product-uuid",
"name": "Wireless Headphones Pro",
"sku": "WH-BT-001",
"imageUrl": "https://cdn.../thumb.jpg",
"slug": "wireless-headphones-pro"
},
"quantity": 2,
"unitPrice": 7990.00,
"totalPrice": 15980.00,
"stockStatus": "IN_STOCK",
"availableQuantity": 45
}
],
"subtotal": 15980.00,
"discountTotal": 0.00,
"total": 15980.00,
"currency": "RUB",
"itemCount": 2,
"referringPartnerCode": "ABC123"
}Эндпоинт обновления количества: PATCH /cart/items/{itemId}
Запрос:
{
"quantity": 3
}Эндпоинт удаления товара: DELETE /cart/items/{itemId}
Сохранить на потом: POST /cart/items/{itemId}/save-for-later
5. Гостевое и авторизованное оформление
Процесс гостевого оформления:
- Сбор email (обязательно)
- Ввод адреса доставки
- Обработка оплаты
- Предложение создания аккаунта (опционально, после покупки)
Ограничения гостевого оформления:
- История заказов только через поиск по email
- Нет сохраненных адресов/способов оплаты
- Нельзя использовать баллы лояльности
- Атрибуция реферала по-прежнему работает
Объединение корзин (при входе гостя):
- Товары гостевой корзины объединяются с корзиной пользователя
- Дублирующиеся товары: количества суммируются
- Атрибуция сохраняется из исходной корзины
6. Оформление Шаг 1: Адрес доставки
Эндпоинт сохраненных адресов: GET /users/me/addresses?type=SHIPPING
Запрос нового адреса:
{
"firstName": "Ivan",
"lastName": "Petrov",
"phone": "+79001234567",
"addressLine1": "ul. Lenina, d. 10, kv. 5",
"addressLine2": "",
"city": "Moscow",
"state": "Moscow Oblast",
"postalCode": "101000",
"country": "RUS",
"saveAddress": true,
"setAsDefault": true
}Валидация адреса:
| Поле | Правила |
|---|---|
| firstName, lastName | Обязательно, 2-100 символов |
| addressLine1 | Обязательно, максимум 255 символов |
| city | Обязательно, максимум 100 символов |
| postalCode | Обязательно, формат зависит от страны |
| country | Обязательно, ISO 3166-1 alpha-3 |
| phone | Обязательно, формат E.164 |
7. Оформление Шаг 2: Способ доставки
Эндпоинт: GET /checkout/shipping-methods
Ответ:
{
"methods": [
{
"id": "method-uuid",
"name": "CDEK Express",
"carrier": "CDEK",
"price": 350.00,
"currency": "RUB",
"estimatedDays": { "min": 2, "max": 4 },
"description": "Fast delivery to your door"
},
{
"id": "method-uuid-2",
"name": "Standard Delivery",
"carrier": "CDEK",
"price": 200.00,
"currency": "RUB",
"estimatedDays": { "min": 5, "max": 7 },
"description": "Economic delivery option"
}
]
}Расчет тарифов:
- На основе: адреса назначения, веса, габаритов
- Кэшируется на 15 минут
- Реальный API-вызов к перевозчику при отсутствии кэша
8. Оформление Шаг 3: Оплата
Поддерживаемые способы оплаты:
| Способ | Провайдер | Возможности |
|---|---|---|
| Кредитная/Дебетовая карта | Stripe | 3D Secure, сохраненные карты |
| Банковская карта (РФ) | YooKassa | Российские карты, SberPay |
| Электронный кошелек | YooKassa | YooMoney, QIWI |
| Банковский перевод | YooKassa | Оплата по счету |
Процесс оплаты (Stripe):
- Frontend создает PaymentIntent
- Пользователь вводит данные карты в Stripe Elements
- Frontend подтверждает оплату
- Backend верифицирует через webhook
Эндпоинт завершения оформления: POST /checkout/complete
Запрос:
{
"paymentMethodId": "pm_xxx",
"paymentIntentId": "pi_xxx",
"billingAddressId": "address-uuid",
"notes": "Leave at door"
}9. Подтверждение заказа
Созданный заказ:
{
"id": "order-uuid",
"orderNumber": "ORD-2024-001234",
"status": "CONFIRMED",
"items": [...],
"subtotal": 15980.00,
"shippingCost": 350.00,
"discountTotal": 0.00,
"taxAmount": 0.00,
"total": 16330.00,
"currency": "RUB",
"shippingAddress": {...},
"shippingMethod": {...},
"createdAt": "2024-01-15T10:30:00Z",
"estimatedDelivery": "2024-01-19"
}Письмо подтверждения содержит:
- Номер заказа и сводку
- Детализированный список с ценами
- Адрес и способ доставки
- Ожидаемую дату доставки
- Контакт поддержки
10. Отслеживание заказа
Эндпоинт: GET /orders/{orderNumber}
Хронология статусов заказа:
| Статус | Описание | Действие пользователя |
|---|---|---|
| PENDING | Заказ создан, ожидает оплаты | Завершить оплату |
| CONFIRMED | Оплата успешна | Ожидать обработки |
| PROCESSING | Подготавливается | Ожидать отправки |
| SHIPPED | Передан перевозчику | Отслеживать отправление |
| DELIVERED | Получен клиентом | Оставить отзыв, запросить возврат |
| CANCELLED | Заказ отменен | Связаться с поддержкой |
| REFUNDED | Деньги возвращены | Н/Д |
Интеграция отслеживания:
- Отслеживание в реальном времени через API перевозчика
- Webhook-обновления при изменении статуса
- SMS/Email-уведомления на каждом этапе
11-12. Выполнение и доставка
Переходы состояний заказа:
PENDING -> CONFIRMED -> PROCESSING -> SHIPPED -> DELIVERED
| | |
v v v
CANCELLED CANCELLED CANCELLED (rare)
|
v
REFUNDEDWebhook-события перевозчика:
| Событие | Действие |
|---|---|
| picked_up | Обновить статус отправления |
| in_transit | Обновить события отслеживания |
| out_for_delivery | Отправить уведомление |
| delivered | Обновить заказ до DELIVERED |
| returned | Инициировать процесс возврата |
13. Послепродажные действия
Отзывы
Эндпоинт: POST /products/{productId}/reviews
Запрос:
{
"rating": 5,
"title": "Great headphones!",
"content": "Sound quality is amazing, battery lasts all day.",
"orderId": "order-uuid"
}Правила отзывов:
- Товар должен быть куплен (заказ DELIVERED)
- Один отзыв на товар от пользователя
- Требуется модерация перед публикацией
Возвраты
Эндпоинт: POST /orders/{orderNumber}/returns
Запрос:
{
"items": [
{
"orderItemId": "item-uuid",
"quantity": 1,
"reason": "DEFECTIVE",
"description": "Left speaker not working"
}
]
}Причины возврата:
| Код | Описание | Срок возврата |
|---|---|---|
| DEFECTIVE | Дефект товара | Полный возврат, 3-5 дней |
| WRONG_ITEM | Получен неправильный товар | Полный возврат, 3-5 дней |
| NOT_AS_DESCRIBED | Не соответствует описанию | Полный возврат, 3-5 дней |
| CHANGED_MIND | Покупатель передумал | Возврат минус доставка, 5-7 дней |
Окно возврата: 14 дней с момента доставки
Сценарии ошибок
Ошибки корзины
| Сценарий | HTTP-код | Код ошибки | Сообщение |
|---|---|---|---|
| Товар не найден | 404 | PRODUCT_NOT_FOUND | "Товар больше недоступен" |
| Нет в наличии | 422 | INSUFFICIENT_STOCK | "Доступно только X товаров" |
| Товар снят с продажи | 422 | PRODUCT_UNAVAILABLE | "Этот товар больше не продается" |
| Корзина пуста | 400 | EMPTY_CART | "Ваша корзина пуста" |
Ошибки оформления
| Сценарий | HTTP-код | Код ошибки | Сообщение |
|---|---|---|---|
| Наличие изменилось при оформлении | 409 | STOCK_CHANGED | "Некоторые товары больше недоступны" |
| Цена изменилась | 409 | PRICE_CHANGED | "Цены были обновлены" |
| Неверный адрес | 400 | INVALID_ADDRESS | "Пожалуйста, проверьте ваш адрес" |
| Доставка недоступна | 422 | SHIPPING_UNAVAILABLE | "Доставка по этому адресу недоступна" |
Ошибки оплаты
| Сценарий | HTTP-код | Код ошибки | Сообщение |
|---|---|---|---|
| Карта отклонена | 422 | CARD_DECLINED | "Ваша карта была отклонена" |
| Недостаточно средств | 422 | INSUFFICIENT_FUNDS | "Недостаточно средств" |
| Ошибка 3DS | 422 | 3DS_FAILED | "Верификация 3D Secure не удалась" |
| Таймаут оплаты | 408 | PAYMENT_TIMEOUT | "Время оплаты истекло, попробуйте снова" |