Привет! Меня зовут Арсений Андреев, я backend-разработчик в Solid — финтех-компании, которая помогает бизнесам принимать онлайн-платежи по всему миру. Также наша платформа обеспечивает их максимальную конверсию при минимальных рисках, используя дополнительные сервисы: антифрод, систему по предотвращению чарджбэков (принудительный возврат платежа), сервис подписок и многие другие.
Прежде чем перейти к техническим деталям, хочу объяснить, что такое антифрод и почему он необходим.
Фрод (fraud) — это мошеннические операции с данными банковской карты пользователя, в нашем случае, в интернете. Система антифрода позволяет обнаружить и предотвратить рисковые операции по картам, которые пытаются провести злоумышленники. Рост электронной коммерции сопровождается и ростом числа мошеннических операций, поэтому для компаний, которые принимают онлайн-платежи, система антифрода очень важна.
В Solid мы ежемесячно проводим миллионы транзакций, и качественная система антифрода — один из наших главных приоритетов.
Мы занимаемся комплексной разработкой инструментов для онлайн-оплат, где один из ключевых инструментов — платежный шлюз. Он позволяет автоматизировать процесс приема платежей в интернете, а антифрод — его неотъемлемая часть.
Помимо предотвращения рисковых операций, система антифрода автоматически анализирует транзакции, минимизирует связанные с фродом расходы и помогает сохранить высокий уровень конверсии.
Ответственность за финансовые риски несет продавец, так как он получает средства от клиента. Могут возникнуть финансовые или репутационные потери и у платежного шлюза, если злоумышленник получит к нему доступ. Поэтому в первую очередь система антифрода служит для минимизации рисков, связанных с кражей денег реального владельца карты.
Основные показатели, на которые мы хотим влиять с помощью системы антифрода:
Итак, главная задача антифрода — минимизация рисков с сохранением высокого уровня конверсии платежей.
Цель системы — выявить аномальные транзакции и принять решение о дальнейшем проведении таких платежей.
После проверки антифродом платежный шлюз должен получить четкую установку, что делать:
Для этого антифрод должен обладать такой информацией:
Одна из главных целей в реализации антифрода — автоматизация процессов риск-менеджмента. Важно предоставить управляющим системой полноценный инструмент, который позволял бы решать повседневные задачи. Речь идет не только о конфигурации, но и о возможности проверки этой системы на корректность работы. Реализация такого функционала могла бы «объяснить» результат проверки антифрода.
Система антифрода должна соответствовать многим требованиям, чтобы решать задачи риск-менеджмента.
Среди них можно выделить:
Система антифрода критически важна. Ее остановка может привести к росту риск-показателей, например, увеличению процента чарджбэков. Как следствие, ваша компания попадет в программу мониторинга международной платежной системы. А это спровоцирует штрафы и санкции против платежного провайдера.
Скорость ответа антифрода — один из главных факторов его эффективности, поскольку проверка осуществляется в момент проведения платежа. Поэтому наш сервис написан на Go — этот язык позволяет распараллелить операции-проверки, необходимые для предоставления заключения платежному шлюзу.
Мы используем PostgreSQL в качестве базы для хранения конфигурационных данных, а Elastic — для сохранения информации о платежах.
В систему антифрода входят такие этапы проверки:
Чтобы определить судьбу транзакции, платежному шлюзу необходим однозначный результат:
Коротко рассмотрим каждый из этапов.
Это первый этап, потому что он наименее ресурсозатратный. Списки хранятся в базе данных (БД) и могут включать разные поля — например, идентификатор карты.
Поскольку у этого этапа проверки самый простой функционал, доступ к нему есть не только у операторов системы, но и у пользователей клиента и других систем мониторинга. Можно сказать, что проверка по включающему/исключающему списку — базовый инструмент для блокировки пользователей.
Списки хранятся в таблице с такими полями:
Несложным SQL-запросом мы проверяем, есть ли совпадение по одному из параметров платежа. Важный момент — если получаем Reject, то следующие проверки уже не производятся.
Пример динамических правил для проверки платежа:
Этот функционал мы реализовали с помощью агрегационных функций Elasticsearch. Все правила по аккаунту, хранящиеся в БД, собираются в один elastic-запрос — JSON-объект. В результате получаем «решение» по каждому из правил. Далее в каждом правиле проверяем значение, полученное из запроса, и формируем список решений (pass, reject и т.п.).
У оператора в арсенале есть набор доступных полей для агрегации:
Операторы сравнения: «in», «not in», «>», «<», «=», «>=», «<=», «!=».
Агрегационные функции:
Таким образом, можно привести несколько примеров настроенных правил:
Оператор системы может настроить любое правило.
Здесь важно выбрать оптимальный вариант хранения по индексам в elastic. Есть возможность хранить данные за короткий период (день) или за продолжительный (месяц).
Оба варианта имеют как плюсы, так и минусы. При хранении в «больших» индексах мы используем больше ресурсов при обновлении данных, что впоследствии негативно влияет на время выполнения поискового запроса. «Маленькие» индексы плохи тем, что при поиске за продолжительный период нужно тратить время на их объединение.
Наша команда выбрала оба варианта. Для выполнения правил, которые используют короткий период (3–5 дней), мы сохраняем данные по дням. Для правил за большой период (более 5 дней) сохраняем данные в одном индексе за продолжительное время. У нас большинство правил настроено на короткий период — 1–3 дня, поэтому такой подход устраивает.
В результате имеем такую разбивку по индексам:
Также стоит учесть, что частая реиндексация значительно влияет на время выполнения поискового запроса. Пример запроса: подсчитать среднюю сумму успешных платежей в USD за последние три часа. Подсчет происходит по нескольким параметрам, идентифицирующим пользователя, например: ID аккаунта, card_id, имейл.
{ "aggs": { "avgUsdSum": { "filter": { "bool": { "must": [ { "term": { "payment_status": ":order_status" } }, { "range": { "created_at": { "gte": "now-180m", "format": "yyyy-MM-dd" } } } ] } }, "aggs": { "avgUsd": { "avg": { "field": "amount_usd" } } } } }, "query": { "bool": { "filter": [ { "bool": { "should": [ { "term": { "email": ":customer_email" } }, { "term": { "card_id": ":card_id" } }, { "term": { "customer_account_id": ":customer_account_id" } } ] } }
Конфигурационные данные хранятся в базе данных. С помощью кода записи в БД, правила трансформируются в запросы (примеры такого запроса приведены выше). После получения данных в ответ на запрос, мы их парсим и сравниваем с заданными в правилах значениями.
В данном случае применяем реализованный аналитиками сервис, который использует модели, построенные на исторических данных клиента. Скор — это число от -100 до 100. Оператор добавляет маппинг в настройках аккаунта, например:
В этот сервис отправляются данные, которые:
Сервис, разработанный на моделях с историческими данными, заслуживает отдельного внимания. Его мы опишем в отдельной статье, поскольку настройка такой модели — сложный процесс, зависящий от многих факторов. Для каждого бизнеса мы формируем уникальную модель, потому что поведение пользователей чаще всего очень разное.
Интеграция со сторонним сервисом — это последний этап проверки. Сервис возвращает не только скор, но и другие параметры, которые можно использовать в конфигурации правил. У каждого сервиса есть свой флоу, но в целом они похожи. Необходимо передать определенное количество параметров, которые помогут этому сервису определить скор.
Одна из проблем реализации антифрода как отдельной системы — наполнение базы данных этой системы платежами. Для получения корректных проверок необходимо держать информацию в актуальном состоянии, в первую очередь — статус платежа.
Например, злоумышленник проверяет большое количество карточных данных за короткий отрезок времени. В таком случае данные о платеже должны обновляться мгновенно, поскольку задержка даже в 1 секунду может стоить нескольких возвратных платежей.
В нашем антифроде обновление данных происходит сразу же после изменения статуса платежа. Таким образом, данные в системе всегда в актуальном состоянии.
Еще интересный момент по поводу корректности работы антифрода. Технически все проверки могут функционировать правильно, но как узнать: заблокированный плательщик был действительно злоумышленником или просто имеет проблемы с вводом своих данных?
В первом случае можно ориентироваться на процент чарджбэков и возвратов. Во втором случае, если пользователь не обратится в службу поддержки (а это бывает очень редко — скорее всего, он просто воспользуется другим сервисом), то мы не узнаем, что блокирование сработало неправильно. Поэтому важна не только исправная техническая система, но и ее конфигурация и поддержка.
Нам удалось реализовать систему антифрода, которую можно гибко настраивать под различные типы бизнесов. Для каждого из них есть ряд уникальных параметров, например, размер среднего чека, особенности товаров и услуг. Важно учитывать специфические для бизнеса параметры, поскольку это позволяет не только держать конверсию на высоком уровне, но и предупредить финансовые потери, связанные с фродом.
Платежный шлюз здорово упрощает жизнь своим клиентам, поскольку им не надо реализовывать сложную систему, которая помимо разработки требует еще и поддержки.
Наша система антифрода дает возможность посмотреть причины блокирования платежа прямо в админке, а также воспользоваться включающими/исключающими списками. При необходимости клиент может предоставить специфические для его бизнеса настройки антифрода, и они будут сконфигурированы риск-менеджментом в данной системе.
Важно, что разработчик исключается из процессов риск-менеджмента. То есть, система предоставляет полноценный функционал по управлению, настройке и мониторингу ее работы. Это позволяет аналитикам выполнять свои повседневные задачи без помощи программистов.
В благословенные офисные времена, когда не было большой войны и коронавируса, люди гораздо больше общались…
Вот две истории из собственного опыта, с тех пор, когда только начинал делать свою карьеру…
«Ты же программист». За свою жизнь я много раз слышал эту фразу. От всех. Кто…
Отличные новости! Если вы пропустили, GitHub Copilot — это уже не отдельный продукт, а набор…
Несколько месяцев назад мы с командой Promodo (агентство инвестировало в продукт более $100 000) запустили…
Пару дней назад прочитал сообщение о том, что хорошие курсы могут стать альтернативой классическому образованию.…