Перейти к содержанию

Политики дополнительного подтверждения

Когда платёж требует от пользователя подтверждения — и каким способом. Объяснение «человеческим языком», без кода и схем.

Зачем это нужно

Не каждый платёж в OneWallet безопасно проводить «в один клик». Кофе за 80 батов — да, тут лишний экран только раздражает. Перевод 50 000 батов незнакомому получателю — нет, тут нужно убедиться, что приложением управляет именно владелец кошелька, а не тот, кто на минуту взял в руки разблокированный телефон.

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

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

Пять уровней подтверждения

PM умеет потребовать ровно один из пяти уровней. Auth Center сам решает, как именно собирать фактор (как выглядит экран, какой текст показать, какой fallback предложить) — PM в этом не участвует.

NONE — без подтверждения

Платёж проходит сразу, как только пользователь нажал «Оплатить». Никаких дополнительных экранов.

Применяется к мелким бытовым операциям, где риск мошенничества низкий, а удобство критично. Типичный пример — оплата кофе, проезда, перевод другу маленькой суммы «скинуться на пиццу».

PIN — ввод PIN-кода

Перед списанием приложение показывает PIN-pad и просит ввести 6-значный код, установленный при регистрации.

Это стандартный, «умолчательный» уровень для большинства платежей. PIN — баланс между безопасностью и удобством: ввести шесть цифр быстро, при этом случайно или «за спиной» это сделать сложно.

BIOMETRIC — Face ID или отпечаток пальца

Приложение запрашивает биометрическое подтверждение средствами операционной системы. Если биометрия на устройстве не настроена или временно недоступна (например, грязный сканер) — Auth Center откатывается к PIN.

Применяется к крупным операциям, где хочется именно «живого» подтверждения от владельца, а не просто знания кода (PIN можно подсмотреть, биометрию — гораздо труднее).

OTP — одноразовый код

Пользователю отправляется код по SMS, e-mail или через authenticator-приложение. Код нужно ввести в течение короткого времени.

В текущем релизе OneWallet OTP активно не используется — заложен как резерв на случай, если биометрия недоступна, либо для отдельных особенно чувствительных сценариев. Уровень полностью поддержан системой и может быть включён без доработок схемы данных.

KYC_UPLIFT — расширенная верификация личности

Самый «тяжёлый» уровень. Платёж не получится провести, пока пользователь не пройдёт повторную процедуру KYC: загрузить документы (паспорт / ID-карта), сделать селфи, дождаться проверки. После успешного прохождения пользователь поднимается на более высокий KYC-tier, и его лимиты расширяются.

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

Когда какой уровень требуется

В стартовой («коробочной») конфигурации Payment Manager работают пять базовых правил. Они описывают наиболее частые ситуации и подобраны так, чтобы покрыть массового пользователя без лишних трений.

Микро-перевод — NONE

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

Граница «100 батов» — это эвристика для запуска. С накоплением статистики мошеннических кейсов её можно опускать или поднимать; в обоих документах нет ни одной зашитой в код константы — всё хранится в правилах.

Стандартный платёж — PIN

Перевод или оплата в диапазоне от 100 до 5 000 батов — самая частая ситуация. Тут просим PIN. Это компромисс: пользователю не нужно ничего настраивать заранее (PIN он и так знает), а злоумышленник без PIN ничего не сделает.

Перевод новому получателю — PIN

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

«Новый получатель» определяется автоматически: PM смотрит, был ли у пользователя хотя бы один успешный платёж этому мерчанту в прошлом. Если нет — это новый получатель. Для обычных P2P-переводов между физлицами (без мерчанта) это правило не срабатывает — там роль «новизны» закрывает базовое правило по сумме.

Крупная сумма — BIOMETRIC

Платёж от 5 000 батов и выше требует биометрии. Это уровень, на котором цена ошибки уже ощутима, и хочется быть уверенным, что подтверждение даёт именно владелец кошелька — а не, скажем, ребёнок, подсмотревший PIN.

Если биометрия на устройстве недоступна, Auth Center откатывается на PIN — пользователь не остаётся «в тупике».

Превышение дневного лимита — KYC_UPLIFT

Если за сегодня пользователь уже потратил 50 000 батов и более (суммарно, по всем успешным списаниям), любая следующая операция запросит KYC-uplift. Дальше — стандартный флоу расширенной верификации.

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

Накопленный за день оборот считается по календарному дню в UTC — то есть «обнуляется» в 7:00 по бангкокскому времени. Это иногда вызывает вопросы у пользователей, привыкших к локальной полуночи; в UI стоит явно подсказывать, когда сбросится счётчик.

Если ничего не подошло — NONE

Если ни одно правило не сработало — например, в системе нет ни одного активного правила для данной комбинации параметров — PM возвращает уровень NONE. Это безопасно по построению: жёсткие лимиты и базовая авторизация всё равно отработают.

Несколько примеров «в прозе»

Чтобы стало совсем понятно, пройдёмся по типовым ситуациям и посмотрим, какой уровень получит пользователь.

Сценарий 1. Сомпонг покупает кофе за 80 батов. Сумма меньше 100 батов, никаких других факторов нет — PM возвращает NONE. Кофе оплачен в один тап, никаких экранов подтверждения.

Сценарий 2. Сомпонг переводит другу 500 батов. Сумма в диапазоне 100…5 000 батов, друг как получатель ему знаком (уже были переводы) — это «стандартный платёж», PM возвращает PIN. Приложение показывает PIN-pad.

Сценарий 3. Сомпонг впервые платит новому продавцу 200 батов. Сумма стандартная, но получатель новый — правило «новый получатель» имеет более высокий приоритет, чем «стандартный платёж», поэтому PM также вернёт PIN. Конечный уровень тот же, но reason-code будет другим — new_payee, и UI может это подсветить пользователю.

Сценарий 4. Сомпонг переводит 8 000 батов родственнику. Сумма выше 5 000 батов — срабатывает правило «крупная сумма», PM возвращает BIOMETRIC. Приложение запросит Face ID; если он недоступен — отступит на PIN.

Сценарий 5. Сомпонг сегодня уже перевёл 48 000 батов и хочет перевести ещё 5 000. Накопленный дневной оборот после этой операции превысит 50 000 батов. Уже на оценке политики PM увидит дневной кумулятив выше порога и вернёт KYC_UPLIFT. Приложение покажет экран «для продолжения нужно пройти расширенную верификацию».

Сценарий 6. Мерчант помечен как high-risk, заведено точечное правило. Любая оплата ему — даже на 50 батов — будет требовать биометрию, потому что у мерчантского правила указан меньший приоритет, чем у «микроплатежа». Это и есть сила scope-overrides.

Как одно правило выигрывает у другого

Все правила имеют приоритет — небольшое целое число. Чем меньше приоритет, тем раньше правило проверяется. PM перебирает правила по возрастанию приоритета и берёт первое, которое подошло. Дальше перебор останавливается.

Это позволяет аккуратно расставлять «исключения». В стартовой конфигурации приоритеты подобраны так:

  1. Сначала проверяется превышение дневного лимита — потому что если оно сработало, то любая другая логика уже неважна, нужен KYC.
  2. Потом — микроплатежи (если сумма меньше 100 батов, дальше ничего проверять не надо).
  3. Потом — новый получатель.
  4. Потом — стандартные пороги по сумме (диапазон 100…5 000 батов).
  5. И в самом конце — крупные суммы.

То есть тяжёлые операции (KYC-uplift) перехватывают управление раньше; «облегчающее» правило про микроплатежи тоже стоит высоко, чтобы оно срабатывало до того, как сумма-в-диапазоне успеет потребовать PIN.

Область применения правила (scope)

У каждого правила есть «область»:

  • Глобальная — действует на все платежи всех пользователей во всех приложениях. Стартовые пять правил, описанные выше, — глобальные.
  • Для конкретного приложения — например, «в мини-приложении лотереи требовать PIN с любых сумм от 500 батов, потому что аудитория более рисковая».
  • Для конкретного мерчанта — например, «при оплате этому конкретному селлеру всегда требовать биометрию, потому что он недавно подключился и считается высокорисковым».

Все три области рассматриваются вместе: PM не делит «сначала проверим мерчантские правила, потом приложенческие, потом глобальные». Он смешивает их в один список и сортирует по приоритету. Это означает, что специальное правило для мерчанта легко может перекрыть глобальное — нужно лишь дать ему меньший приоритет.

Что меняется со временем

Стартовая конфигурация — это не «закон»: правила хранятся в обычной таблице и могут обновляться без перевыпуска приложения. Типовые сценарии изменений:

  • Меняются пороги. Например, инфляция привела к тому, что 5 000 батов уже не «крупная сумма» — поднимаем порог до 10 000.
  • Появляется новое приложение. Для него заводят отдельные правила в его «области».
  • Появляется high-risk-мерчант. Заводим для него точечное правило с биометрией.
  • Запускается OTP-провайдер. Включаем уровень OTP — добавляем правила, в которых он используется.

Изменения вступают в силу немедленно — PM не кэширует правила между вызовами, читает таблицу свежей на каждый запрос. Это удобно при подкрутке настроек, но требует осторожности: ошибочное правило с низким приоритетом и пустым условием способно «выключить» всю систему step-up. На практике изменения правил обычно идут через Admin Panel или подготовленную миграцию.

Что ещё важно знать продакту

  • Политики не отменяют лимиты. Если PM-лимит говорит «нельзя» (например, превышен месячный потолок) — никакой PIN или биометрия его не разблокируют. Политики и лимиты — это два разных механизма, которые работают вместе.
  • Политики оценивают момент инициации. Между тем, как Auth Center спросил «нужен ли PIN», и тем, как пользователь нажал «Подтвердить», состояние может слегка измениться (другой платёж успел пройти). Это допустимо: финальные жёсткие проверки делает уже сам этап создания платежа.
  • Административные операции не идут через политики. Когда оператор Admin Panel делает возврат или корректировку, политики не вызываются — там действует другой механизм авторизации (сервисная подпись), а ответственность за легитимность операции лежит на самом операторе.
  • Reason-code. Вместе с уровнем PM возвращает короткий код причины (например, large_amount, new_payee, daily_limit). Приложение использует его, чтобы показать пользователю осмысленное объяснение — «требуется биометрия, так как сумма выше 5 000 батов» — а не безликий запрос на подтверждение.
  • Состояние не зависит от устройства. Решение принимается на стороне сервера и одинаково для всех устройств одного пользователя. Если пользователь поменял телефон, политики продолжают работать с того же места.
  • Аналитика и аудит. Каждый ответ PM содержит идентификатор сработавшего правила. Это позволяет в дальнейшем анализировать, какие пороги срабатывают чаще всего, насколько они мешают пользователям, и принимать решения о пересмотре по данным, а не по интуиции.

Где это в коде

  • Техническое описание движка политик, его API и поведения матчера — ../dev/modules/policies.md.
  • Структура таблицы с правилами, поля, индексы и примеры SQL для добавления и изменения правил — ../dev/reference/database/08-auth-policies.md.