﻿---
title: Надёжность и безопасность магазина
description: Кэширование витрины без персональных данных, секреты, webhook, антифрод и e2e-сценарии отказа.
---

TL;DR: Страница покрывает надёжность и безопасность магазина на уровне процессов: что можно кэшировать публично, а что содержит персональные цены и корзины, как защищать webhook-эндпоинты и восстанавливать резервные копии, как выглядит бизнес-мониторинг шире uptime. Базовые веб-меры (WAF, хардненинг, сканеры) описаны в разделе [безопасности сайтов](https://wpcraft.ru/kb/practices/web/security.md) и здесь не дублируются.

## Кэширование витрины

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

| Контент | Кэшировать публично (CDN/reverse proxy) | Считать на сервере и не кэшировать |
| --- | --- | --- |
| Каталог, карточки, баннеры | Да | — |
| Статические ассеты | Да | — |
| Остатки и цены | Осторожно: публично только если цены единые для всех; иначе — частично (etag, короткий TTL), остатки на сервере | Да, если цены зависят от клиента или сегмента |
| Корзина | Никогда | Да |
| Личный кабинет | Никогда | Да |
| Checkout любой шаг | Никогда | Да |
| Персональные цены, бонусы | Никогда | Да |

Простой ориентир: то, что одинаково у всех посетителей, может кэшироваться агрегатно; всё, что зависит от сессии, cookie, авторизации, сегмента клиента или группы (B2B), кэшированию не подлежит. Промежуточный вариант — кэшировать «каркас» страницы (шаблон, меню, категории), а персональные блоки (имя, бонусы, корзина) подгружать отдельным запросом.

Правильность разделения проверяет тест: один пользователь кладёт товар в корзину, второй открывает сайт из кэша — видеть чужой товар он не должен. Опасное место — reverse proxy и CDN: правило кэширования, описанное в документации, не всегда совпадает с фактическим заголовком `Cache-Control` от приложения.

## HTTPS, секреты, роли и audit log

HTTPS на всей витрине — базовое требование; выделение HTTPS только для checkout и кабинета недостаточно: cookie могут перехватываться на обычных страницах. Cookies сессий — `Secure`, `HttpOnly`, `SameSite`; конкретные требования уточняются профильным ревью.

Хранение секретов: ключи платёжных шлюзов и API учётных систем не в репозитории и не в общих документах. Хранилище секретов с ротацией; у каждого секрета указано, какая система или процесс его использует — иначе ротация ломает работающий интеграционный поток.

Роли и аудит: у админки магазина как минимум три роли, а не одна «админ»: работа с заказами (просмотр и статусы), работа с контентом (каталог и цены), управление доступами и настройками. Каждое значимое изменение (цена, остаток, статус заказа, выдача скидки, создание промокода) попадает в audit log: кто, что, когда, откуда (IP/сессия). Содержимое audit log нельзя редактировать через интерфейс администратора; при возможности он хранится отдельно от основной базы.

## Backup/restore с проверкой восстановления

Бэкап магазина должен закрывать три класса данных: базу (заказы, клиенты, товары), файлы (карточки, контент, выгрузки для остатков и фидов) и конфигурацию (env, nginx, docker/podman определения). Расписание и полномасштабное восстановление с проверкой — см. [операционную готовность](https://wpcraft.ru/kb/practices/ecommerce/operations.md). Минимум для магазина дополнительно:

- Восстановление проверяется на копии prod, а не на пустом стенде: магазин нужно поднимать вместе с очередями и связями, а не только с файлами.
- База данных и файловое хранилище восстанавливаются с согласованной точкой времени: заказ, оплаченный в 14:00, и его чек из базы — соседние данные; разрыв между ними чреват расхождениями в фискализации.
- Допустимое окно потери данных (RPO) магазин выбирает по объёму ежедневных продаж: оно должно быть не больше, чем «продажи на N часов», которые бизнес готов повторно обработать вручную.

## Защита webhook-эндпоинтов

Webhook-и — эндпоинты, на которые внешние системы (платёжный шлюз, CRM, учётная система, логистика) присылают события о статусах. Два базовых требования:

1. **Подпись и аутентификация.** Шлюз подписывает запрос секретом; сервер проверяет подпись, а если протокол подписи не предусматривает — ограничивает доступ по списку IP-адресов источника. Эндпоинт, принимающий любые запросы «как есть», открывает путь к фальшивым статусам «оплачено».
2. **Идемпотентность.** Системы отсылают один и тот же webhook повторно при сомнении в доставке. Обработка должна сводить повторные запросы к одному результату: ключ идемпотентности — ID события или «ID заказа + статус»; повтор означает обновить, а не продублировать (второй чек, вторая отправка, двойное списание бонусов — типовые последствия дублирования).

Дополнительно: очередь приёма webhook — буфер пиков. Если шлюз шлёт всплеск событий, а учётная система занята, очередь хранит события без потери; потерянный webhook о «оплачено» разбирать дороже, чем хранить очередь.

## Антифрод

Стандартный набор признаков: серия попыток оплатить одной картой, множественные неудачные оплаты с одного IP, заказ с самовывозом без личной верификации, необычно большая корзина у нового клиента, несоответствие имени держателя карты и получателя. Реализация в магазине: правила на уровне платёжного шлюза (обязательный 3-D Secure для рисковых сегментов, лимит операций по карте), ручная проверка подозрительных заказов перед отправкой, отдельная проверка контрагентов в B2B.

Антифрод всегда баланс между защитой и отсевом: слишком жёсткие правила теряют настоящих клиентов. Каждое правило блокировки обосновывается явно и периодически пересматривается, а не работает «навсегда».

## Очереди как буфер пиков

Работа, которую система делает в момент заказа, разделяется на:

- **Синхронную дорогу** (должна завершиться до ответа клиенту): создание заказа, резервирование остатка, запрос ссылки оплаты.
- **Асинхронные задачи** (могут опоздать на минуты): email и уведомления, выгрузка в учёт, обновление фида, генерация чеков, передача в логистику.

Асинхронные задачи кладутся в очередь. Очередь спасает в пиках — письма не замедляют checkout — и в отказах: при недоступности учётной системы заказы накапливаются и обрабатываются, когда она поднимется. Обратная сторона: сама очередь становится наблюдаемым объектом (длина, возраст самой старой задачи, число повторных попыток) и входит в бизнес-мониторинг ниже.

## Бизнес-мониторинг шире uptime/p95

Здоровье сайта (uptime, p95) покрывает вопрос «работает ли сайт». Бизнес-мониторинг отвечает на другой вопрос: «всё ли обработано, что должно быть обработано».

| Сигнал | На что смотреть |
| --- | --- |
| Отставание остатков | Задержка выгрузки остатков из учётной системы в витрину; лимит (например, 30 минут — число условное) |
| Отставание цен | Задержка согласования цен между учётом и магазином |
| Необработанные заказы | Возраст заказов без перехода в «обработан» после оплаты |
| Платёжные ошибки | Доля failed/aborted платежей за час; всплеск даже при зелёном аптайме |
| Ошибки ЭДО | Заказы, у которых документ не проведён; блокирует отгрузку и оплату по счёту |
| Застрявшие отправления | Посылки со статусом, который не менялся дольше X дней (X зависит от перевозчика) |
| Очередь задач | Длина очереди и возраст самой старой задачи |
| Свежесть фидов | Возраст последней успешной выгрузки товарного фида (см. [маркетинг](https://wpcraft.ru/kb/practices/ecommerce/growth/marketing-and-loyalty.md)) |

У каждого сигнала — порог и канал уведомления; часть метрик доступна напрямую в системах, часть собирается контрольными запросами («раз в час — запрос к API учётной системы, сравнить число заказов за вчера»). Главное — у каждого сигнала есть лимит и канал уведомления, а не «раз в неделю посмотрим на отчёты».

## E2E-сценарии: нормальный и аварийный путь

**Нормальный путь.** Клиент выбрал товар → заказ создан → остаток зарезервирован → оплата подтверждена шлюзом → магазин выписывает чек → заказ уходит в логистику → посылка вручена → события синхронизируются в учёт. Каждое звено проверяется двусторонне: заказ виден в магазине, статус подтверждён шлюзом, чек соответствует позиции, отгрузка изменяет остаток.

**Аварийный путь: платёж прошёл, заказ не создался.** Клиент оплатил, но сервер упал между ответом шлюза и сохранением заказа. Что должна делать система:

1. Заказ не создан (транзакция не зафиксирована) — но шлюз деньги списал.
2. Сверка (reconciliation) по открытым платежам: магазин пробегает по неоплаченным/незавершённым заказам, находит платежи со статусом «успешно», для которых нет заказа. По ним создаётся заказ из данных шлюза в упрощённом виде или запускается возврат.
3. Человек (менеджер) проверяет результат: заказ создан или деньги вернули; клиент получает уведомление с извинением и точным статусом.

Обратный сценарий планируется тоже: заказ создан, уведомление об оплате не дошло (недоступность шлюза или webhook). Клиенту — повторная попытка оплаты по той же корзине, а не повторное оформление всего с нуля. Каждый из этих путей фиксируется в runbook, а не «придумывается на месте».

Третий сценарий — частичная согласованность: заказ создан, деньги списаны, но webhook потерялся. Здесь срабатывает идемпотентность и сверка: обработчик webhook воспринимает повторную отправку шлюза как обновление статуса, а не новый заказ; иначе появляются дубли чеков и двойные отправки. Сверка по открытым платежам закрывает кейс, когда повтор не пришёл вовсе.

## Исключения и краевые случаи

- **Кэш с параметрами URL:** страницы с utm-метками и фильтрами нельзя кэшировать одной копией «на весь трафик» — правило кэширования фиксирует, какие параметры игнорируются, а какие порождают отдельный кэш.
- **Персональные цены у одного клиента внутри общего каталога:** даже одна группа B2B с индивидуальным прайсом выводит страницы каталога из-под её публичного кэша — либо короткий TTL, либо подгрузка цены отдельно.
- **Webhook replay с легитимной подписью:** повторные отправки шлюза подписаны правильно; без идемпотентности ключ «подписано» не спасает от дублей.
- **Задержка очереди как «здоровое состояние»:** в пиках очередь растёт — это нормально; проблема фиксируется только по порогу возраста самой старой задачи, а не по длине очереди.
- **Ручное восстановление при частичном отказе:** восстановление из бэкапа ради одной перепутанной цены ломает актуальные заказы; точечные правки предпочтительнее полного restore, если целостность не задета.

## Критерии выбора подхода

- Что кэшировать решается жёстким списком из таблицы выше, а не «по ощущению» — ошибка кэша пользователь не замечает, а магазин теряет доверие.
- Секреты и роли дороже производительности: доступ «на всех» экономит минуты и создаёт путь к изменению цен без следа.
- Бизнес-мониторинг дешевле, чем разбирать последствия: сигнал об отставании остатков за минуту до перепродажи дешевле, чем звонок недому клиента.
- Сверки по платежам ставятся по расписанию (раз в сутки — минимум при активных продажах), чтобы аварийный сценарий ловился в окне, а не через неделю.

## Связанные страницы

- [Обзор контура эксплуатации](https://wpcraft.ru/kb/practices/ecommerce/operations.md) — чек-лист готовности, бизнес-SLA, контроль ручных операций.
- [Требования РФ: матрица применимости](https://wpcraft.ru/kb/practices/ecommerce/operations/compliance.md) — применимость требований по осям B2C/B2B, товар, способ продажи и оплаты.
- [Безопасность сайтов](https://wpcraft.ru/kb/practices/web/security.md) — базовые веб-меры: WAF, хардненинг, защита от ботов и брутфорсов.
- [Системы и потоки данных](https://wpcraft.ru/kb/practices/ecommerce/integrations/systems-and-data-flows.md) — откуда и куда течёт данные магазина, включая webhooks.

## Материалы и источники

- [OWASP Application Security Verification Standard](https://owasp.org/www-project-application-security-verification-standard/) — перечень проверок уровня приложения (аутентификация, сессии, криптография), применимых к магазину.