Skip to content

Карточные данные и токены

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

Два разных токена

Шлюз меняет карту не на один идентификатор, а сразу на несколько, и путать их нельзя: у них разное время жизни и разное содержимое.

Что этоЧто внутриГде лежитСколько живёт
Токен картыНомер и срок действияОсновная база сервиса токенизацииПостоянно
Токен сессииНомер, срок, код проверки, имя держателяRedisОколо часа

Токен карты постоянный. На одну и ту же карту сервис всегда возвращает один и тот же идентификатор: перед созданием записи он ищет существующую по хэшу карты. Благодаря этому карту можно узнать между платежами — на этом держатся рекуррентные списания, сохранённые на нашей форме карты и поиск всех операций по одной карте. Токенов карты на самом деле два: один считается по номеру со сроком действия, второй — только по номеру. Второй нужен там, где карту надо узнать независимо от перевыпуска с новым сроком.

Токен сессии временный. Это зашифрованная строка с полными данными карты, включая код проверки и имя держателя, положенная в Redis с ограниченным сроком жизни. Срок задаёт вызывающий, но сверху он ограничен настройкой самого сервиса, так что бесконечную сессию завести нельзя.

И карта, и сессия шифруются ключом AWS KMS: в хранилищах лежит только шифртекст, ключа там нет. Хэш, по которому ищется дубликат карты, тоже вычисляется ключом KMS, а не обычной хэш-функцией, — подобрать по нему номер перебором не выйдет.

Почему код проверки не хранится

Код проверки (CVV) нельзя хранить после проведения операции — это прямое требование платёжных систем, и именно оно объясняет, зачем понадобилась сессия. Банку код нужен ровно один раз, в момент авторизации, а значит достаточно подержать его несколько минут и забыть. Поэтому код живёт только внутри временной сессии и исчезает вместе с ней; в постоянной записи о карте его нет и быть не может.

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

Токен обратим, и это не анонимизация

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

Данные обратно запрашивают в нескольких случаях. Ядро достаёт содержимое сессии перед тем, как отправить платёж в банк, и отдаёт его драйверу. Драйвер получает карту, когда банк требует реквизиты в своём формате. Выплаты и повторы зависших операций восстанавливают карту по постоянному токену. Бэкофис показывает полный номер, когда сотрудник разбирает инцидент, — но только тем, у кого есть отдельное право доступа, и каждый такой просмотр записывается в журнал действий. Наконец, есть режим, когда нужен не номер, а только его вид: сервис отдаёт маскированную строку, в которой видны первые и последние цифры.

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

Как сервис понимает, что пришёл свой

Сервис токенизации не смотрит наружу: к нему обращаются только наши сервисы, и каждый запрос подписан. Подпись вычисляется ключом AWS KMS, а проверяется тем же ключом на стороне сервиса — значит, подписать запрос может лишь тот, кому выдан доступ к ключу. В теле обязателен штамп времени, и если он расходится с текущим больше чем на несколько секунд, запрос отклоняется: перехваченный запрос нельзя отправить повторно.

Проверяется только это. Сервис не разбирает, кто и зачем спрашивает карту, и не знает ничего про транзакции и статусы. Ограничение доступа к ключу — и есть вся модель доверия, поэтому обращение к токенизации из нового сервиса решается не кодом, а выдачей доступа.

Что это значит для разработчика

  • Не пишите в логи номер карты и код проверки. PCI-шлюз маскирует их в своих логах сам, но как только вы достали карту детокенизацией, ответственность ваша: любой отладочный вывод рискует уехать в общее хранилище логов.
  • Не передавайте карту туда, где её раньше не было. Антифрод, аналитика, уведомления, очереди, тела ошибок, сторонние SDK — всё это работает с токеном и маскированным номером, и так и должно остаться.
  • Не складывайте карточные данные в свои таблицы и кэши, даже временно. Единственное место, где им положено лежать, уже существует.
  • Новый сценарий, в котором появляется настоящая карта, живёт в PCI-контуре — в шлюзе для карточных данных, а не в ядре и не в обычном merchant API. Почему так — в Почему шлюзов несколько.
  • Детокенизация — не бесплатная операция: это поход в соседний сервис и в KMS. Запрашивайте карту там, где она нужна, и не носите её по коду дальше.

Куда дальше

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