RSS
18 октября 2026

Как не дать пользователю заплатить дважды — и остаться в законе

Наткнулся на разбор реализации платежей в AI-продукте с ЮKassa. Не просто «как заплатить», а как не дать пользователю заплатить дважды, не дать скидке сработать, если она уже не действует, и не дать сбоям из-за ручного ввода. Это про то, как система думает о безопасности и законе — и как это касается любого сайта с формой заявки.

О чём речь и почему это важно для сайта

Речь о том, как работает оплата в системе, где пользователь вводит купон, смотрит итог, нажимает кнопку — и всё должно быть честно. Не просто «заплатил», а «заплатил один раз, по той цене, которую видел». Это не про технику, а про доверие. Если у вас есть форма заявки — вы оператор персональных данных. И если в системе нет контроля над тем, что попадает в базу, — это уже риск по 152-ФЗ.

Я считаю, что это важно не потому, что «всё должно быть безопасно», а потому, что если система не проверяет, что пользователь видит, — он может заплатить дважды, а потом не понять, за что. Или скидка сработает, хотя уже не действует. Это не баг — это нарушение. А нарушение — это не просто штраф, это потеря доверия.

Как это устроено — что тут вообще происходит

Система не доверяет клиенту. Ни вводу, ни кликам. Купон проверяется на сервере — не в браузере, не в React. Даже если пользователь меняет цену вручную, это не повлияет на итог. Сумма считается на бэкенде, с учётом скидок, с округлением по правилам. И только после этого формируется платеж.

Кнопка оплаты блокируется, чтобы не дать двойному клику. Но это не главное. Главное — Idempotence-Key. Каждый запрос получает уникальный ключ. Даже если пользователь перезагрузит страницу или откроет два таба — система узнает, что это один и тот же платеж. Это не про удобство, а про то, чтобы не создавать дубли в базе.

Как понять, что это касается вашего сайта

Если у вас есть форма заявки — вы уже оператор персональных данных. И если в этой форме есть поле для оплаты, купона, тарифа — вы уже в зоне риска. Даже если вы используете сторонний сервис, как ЮKassa, — контроль должен быть на вашей стороне.

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

Что с этим делать — что я делаю в таких случаях

Первое — перенести расчёт цены на сервер. Ни в коем случае не доверять React. Если пользователь может изменить цену в DOM — это уязвимость. Даже если вы используете кэш, это не оправдание.

Второе — перепроверять купоны при каждом платеже. Не только при валидации, но и при создании платежа. Даже если он был проверен пять минут назад — он мог стать неактивным. И третий пункт — использовать уникальные ключи для каждого запроса. Это не про удобство, а про то, чтобы не создавать дубли. Это можно сделать даже без сложных систем — просто генерировать UUID на бэкенде при каждом запросе.

Что здесь даёт поддержка

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

Работаем с 2002 года, более 100 клиентов по всему миру. У нас есть сертификаты PHP и MySQL у всех разработчиков, мониторинг доступности 24/7. Приглашаем на бесплатный аудит сайта — проверим, как устроена ваша форма заявки и оплата.

Как не дать пользователю заплатить дважды — и остаться в законе

← Все материалы