Skip to content

Почему шлюзов несколько

Запрос мерчанта может прийти на два разных публичных адреса, и это не дублирование, а требование PCI DSS. Разделение простое: всё, что содержит номер карты, принимает отдельный шлюз в отдельном контуре; всё остальное — обычный шлюз.

Два контура

Обычный merchant APIPCI-шлюз
Сервисapi-gateway-generalapi-gateway-pci
Доменapi-gateway.smartcore.prochd-api.smartcore.pro
AWS-аккаунтprod-generalprod-pci
Что принимаетСоздание платежа со ссылкой на форму, проверка статуса, выплаты, онрамп, ARSПлатёж с картой, токенизация, оплата картой на нашей форме, выплата с вводом карты
Карточные данныеНе принимает никогдаЕдинственная точка входа для них

Кто в каком контуре живёт

Разделены не только шлюзы, а весь карточный путь: контур — это отдельный AWS-аккаунт со своей сетью и своим доступом.

Здесь видно главное: в PCI-контуре живут только те сервисы, которым настоящий номер карты нужен по существу, — шлюз, который его принимает, хранилище карт, драйверы, передающие карту в банк, и выпускающий виртуальные карты card-manager. Ядро, антифрод, доставка колбеков и всё остальное работают исключительно с токенами и в аудит PCI DSS не попадают.

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

Платёжная форма — исключение, которое стоит понимать. Сама страница живёт в общем контуре, но введённые карточные данные отправляет напрямую в PCI-шлюз, минуя своё окружение.

Смысл разделения в том, чтобы область аудита PCI DSS оставалась маленькой. Чем меньше кода и инфраструктуры видит настоящий номер карты, тем дешевле и надёжнее сертификация. Поэтому PCI-шлюз умеет мало: принять карту, обменять её на токены и передать дальше уже обезличенный запрос.

Что из этого следует для разработки

Новая ручка без карточных данных идёт в api-gateway-general. Это целевой публичный шлюз merchant API, на него постепенно переезжает всё остальное.

Ручка, принимающая карту, идёт в PCI-шлюз — и там же обязана сразу токенизировать данные, не передавая их дальше в открытом виде.

Исторический TypeScript-шлюз ещё держит часть операций. Возвраты, рекуррентные платежи, двухстадийные операции и часть выплат пока живут только в нём, поэтому при поиске кода конкретной ручки проверяйте оба сервиса. Новую функциональность туда не добавляют.

Что шлюз делает и чего не делает

Оба шлюза — тонкий слой. Они проверяют, что запрос пришёл от известного мерчанта, приводят его к внутреннему формату, подписывают и передают в ядро.

Бизнес-логики в шлюзе нет: он не выбирает банк, не считает комиссию, не меняет статусы и не принимает решения об отказе. Единственное исключение — токенизация карты в PCI-шлюзе, и это не бизнес-логика, а требование контура.

Если вы ловите себя на желании добавить в шлюз условие «а для такого мерчанта сделать иначе» — почти наверняка это условие должно жить в ядре.

Как мерчант аутентифицируется

Одинаково на обоих шлюзах: либо Basic с парой «ключ мерчанта — секрет», либо подпись по отсортированным значениям тела. Проверяет не шлюз, а сервис авторизации — шлюз только спрашивает у него, валидны ли данные. Отдельные служебные эндпоинты используют собственные ключи, а публичные страницы формы аутентификации не требуют вовсе. Разбор всех механизмов — в Аутентификация и подписи.

Внутренняя база знаний. Нашли неточность — поправьте страницу или заведите вопрос в разделе «Открытые вопросы».