Старая кнопка Telegram-бота отменяет новый заказ: как связать действие с состоянием

Клиент оформил заказ, получил сообщение с кнопкой отмены, затем изменил условия через сайт. Через день он нашёл старое сообщение и нажал кнопку. Если обработчик доверяет только значению «cancel» и текущему заказу пользователя, он может отменить уже другую заявку. Скрыть старую клавиатуру полезно для интерфейса, но этого недостаточно для защиты бизнес-действия.
У кнопки должен быть конкретный предмет
Команда должна ссылаться на определённый заказ или серверную запись действия. Значение «последний заказ этого пользователя» нестабильно: после отправки сообщения появился новый объект. Сохраните связь с тем объектом, который человек видел при получении предложения.
В Telegram поле callback_data ограничено 1–64 байтами, поэтому длинные описания и весь заказ туда не помещают. Практический вариант — короткий непрозрачный идентификатор серверной записи. В ней хранят объект, допустимое действие, версию, срок и область пользователя. Сам идентификатор ещё не является разрешением выполнить операцию.
Четыре вопроса до изменения заказа
| Вопрос | С чем сравнивать | Что сообщить при несовпадении |
|---|---|---|
| Кто нажал? | Отправитель callback и действующие права на объект | Действие недоступно; без раскрытия чужих данных |
| То ли состояние показано? | Сохранённая версия и актуальная версия заказа | Данные изменились, откройте актуальную карточку |
| Не истекло ли предложение? | Серверное время и заданный срок | Предложение устарело, запросите новое |
| Разрешён ли переход сейчас? | Текущее состояние и правила процесса | Операция уже выполнена или сейчас недопустима |
Идентификаторы пользователей лучше обрабатывать как строки, не преобразуя без необходимости в короткое целое число. Для группового сценария проверка сложнее простого совпадения с владельцем: у менеджера может быть разрешённый доступ к нескольким заказам, у участника группы — только право чтения. Такая политика определяется на сервере.
Ответ на нажатие и результат заказа — разные сообщения
Telegram показывает индикатор ожидания, пока бот не вызовет answerCallbackQuery. Это подтверждение обработки нажатия, а не доказательство отмены заказа. Пользователь не должен видеть «Заказ отменён» до подтверждённого сохранения результата в вашей системе.
Если внешняя CRM отвечает долго, можно подтвердить получение нажатия нейтральным сообщением и затем отдельно показать окончательный исход. При отказе объясните следующий шаг: открыть новую карточку, связаться с поддержкой или дождаться обработки. Не оставляйте бесконечно крутящийся индикатор вместо понятного ответа.
Между проверкой и записью заказ способен измениться
Последовательность «прочитать версию, проверить, записать» не защищает от параллельного действия другого оператора. На рабочем сервере условие версии и переход состояния проверяются в операции изменения или подходящей транзакции. Если изменена не ожидаемая версия, обработчик возвращает конфликт, а не перезаписывает новый результат.
Повторная доставка одного события и два разных нажатия требуют отдельной политики повторов. Идентификатор callback помогает отслеживать конкретное событие, но не заменяет бизнес-ограничение. Два разных события не должны дважды выполнять необратимое действие с одним заказом.
Проверьте отказ до подключения настоящего бота
Ниже находится локальная модель допуска одной операции cancel для условного заказа. Она разрешает отмену только владельцу, при совпавшей версии, состоянии pending и неистёкшем сроке. При равенстве текущего времени сроку предложение уже считается истёкшим. Эти названия и правила учебные, они не описывают готовый продукт студии или обязательное поведение Telegram.
Инструмент собирает причины отказа, а не выбирает первую попавшуюся. В настоящем интерфейсе подробности для чужого пользователя показывать нельзя: из диагностического результата легко узнать внутреннее состояние объекта. Для журнала используйте безопасные идентификаторы и причины, избегая токенов и полного содержимого callback.
Проверка выполняется только над введёнными полями: подлинность запроса, реальная запись заказа, одноразовость идентификатора и конкурентная транзакция здесь отсутствуют. Положительный результат означает согласованность учебных условий, а не разрешение обращаться к боевому API.
Сценарии для приёмки
- Старая карточка после изменения заказа через сайт.
- Нажатие другим человеком и повтор после успешной отмены.
- Одновременная отмена в кабинете и через бота.
- Истечение срока ровно в момент обработки.
- Недоступная исходная карточка сообщения при сохранённом серверном контексте.
Хороший бот сохраняет смысл действия, даже когда переписка длинная, сообщений много и клиент возвращается спустя время. Кнопка остаётся удобным способом попросить об операции; решение о её допустимости принимает актуальная бизнес-система.
Проверить учебные условия отмены из старой кнопки
Локальная модель условий, не проверка Telegram-запроса. Сравнение только с владельцем; реальные роли, подписи, одноразовость и атомарная запись не реализованы. Расчёт выполняется на вашем устройстве, введённые данные никуда не отправляются.
Материалы для проверки
Если нужна реализация
Состав работ зависит от текущего проекта и подтверждённой причины. Можно обсудить диагностику или разработку подходящего решения.
