Повторные уведомления об оплате
Подпись по исходным байтам и обработка дубля в базе.
Платёжный шлюз может повторить уведомление, если не получил ответ вовремя. Покупка при этом одна. Обработчику нужно узнать, что он уже выполнил выдачу.
В TelegramShop читаю исходное тело запроса, вычисляю подпись и сравниваю через hmac.compare_digest. JSON разбирается после этой проверки. Если пересобрать его раньше, порядок полей или пробелы могут измениться — получится другое тело для подписи.
Отсутствующая подпись и ненастроенный ключ должны заканчивать обработку отказом. Иначе условная проверка легко превращается в пропуск: заголовка нет, сравнивать нечего, код идёт дальше.
Для повторов в минимальном магазине использую уникальный telegram_payment_charge_id. База принимает новую запись один раз. В справке для внешних шлюзов есть условный UPDATE: перевести счёт в paid, если он ещё не оплачен, и начислить баланс в той же транзакции. Решение принимает операция базы; два параллельных запроса не должны оба получить право на начисление.
Уже обработанный дубль получает успешный HTTP-ответ. Ошибка отправки сообщения покупателю не повторяет начисление. Внешняя выдача требует своего состояния и повторов — запись платежа сама по себе её не завершает.
Эти приёмы собрал в skill-tg.
