Локальное тестирование вебхуков CloudPayments через TunnelHunt
Пошаговый гайд по отладке уведомлений о платежах CloudPayments на localhost. Как настроить адреса уведомлений, пробросить туннель и верифицировать подпись HMAC-SHA256 в Python.

Сервис CloudPayments отправляет уведомления о платежах, возвратах и подписках в виде HTTP POST-запросов (вебхуков). У системы гибкие настройки уведомлений: вы можете раздельно обрабатывать успешные транзакции (Pay), ошибки (Fail), отмены (Void) и другие события.
Поскольку серверы CloudPayments работают во внешней сети, протестировать обработчики платежей напрямую на localhost невозможно. В этой инструкции мы настроим прием и отладку вебхуков CloudPayments локально с помощью TunnelHunt.
Шаг 1: Создаем обработчик вебхуков на Python (Flask)
Для проверки подлинности вебхуков CloudPayments использует заголовок Content-HMAC-SHA256. В нем передается цифровая подпись, вычисленная как HMAC-SHA256 от сырого тела HTTP-запроса с использованием вашего секретного ключа API (API Secret) в качестве ключа.
[!IMPORTANT] Очень важно вычислять подпись именно от оригинального сырого тела запроса (
request.get_data()), а не от уже распарсенного JSON. Любое изменение в пробелах или порядке полей нарушит подпись.
[!TIP] В macOS Monterey и выше порт
5000используется системной службой AirPlay. Запустим наш сервер Flask на порту8000.
Создайте файл app.py:
# app.py
import hmac
import hashlib
import base64
from flask import Flask, request, abort
app = Flask(__name__)
# Секретный API Secret из личного кабинета CloudPayments (раздел Сайты -> Настройки)
CP_API_SECRET = "your_cloudpayments_api_secret"
def verify_cloudpayments_signature(raw_body, received_signature, api_secret):
if not received_signature:
return False
# Вычисляем HMAC-SHA256 от сырого тела (bytes)
hash_handler = hmac.new(
api_secret.encode('utf-8'),
raw_body,
hashlib.sha256
).digest()
# Кодируем результат в Base64
calculated_signature = base64.b64encode(hash_handler).decode('utf-8')
# Сравниваем полученную и рассчитанную подписи
return hmac.compare_digest(calculated_signature, received_signature)
@app.route('/webhook/cloudpayments', methods=['POST'])
def cloudpayments_webhook():
# 1. Получаем сырое тело запроса и заголовок с подписью
raw_body = request.get_data()
signature = request.headers.get('Content-HMAC-SHA256')
# 2. Проверяем подпись
if not verify_cloudpayments_signature(raw_body, signature, CP_API_SECRET):
print("🚨 Ошибка: Неверная цифровая подпись CloudPayments!")
abort(403)
# 3. Парсим JSON и обрабатываем заказ
json_data = request.get_json(silent=True) or {}
print("🎉 Вебхук CloudPayments успешно верифицирован!")
print(f"ID транзакции: {json_data.get('TransactionId')}")
print(f"Сумма: {json_data.get('Amount')} {json_data.get('Currency')}")
print(f"Статус: {json_data.get('Status')}")
# CloudPayments ожидает ответ с JSON-объектом {"code": 0} в случае успеха
return {"code": 0}, 200
if __name__ == '__main__':
app.run(port=8000, debug=True)
Установите Flask и запустите обработчик:
pip install Flask
python app.py
Сервер запущен на http://localhost:8000/webhook/cloudpayments.
Шаг 2: Пробрасываем туннель через TunnelHunt
Сделаем наше Flask-приложение видимым из интернета. Откройте новый терминал и выполните:
ssh -R 80:localhost:8000 -p 2222 tunnelhunt.ru
Система выдаст публичный URL, например:
https://sleepy-owl.tunnelhunt.ru
Теперь любой запрос на https://sleepy-owl.tunnelhunt.ru/webhook/cloudpayments будет безопасно доставлен в ваше локальное Flask-приложение.
Шаг 3: Настраиваем адреса уведомлений в CloudPayments
- Войдите в Личный кабинет CloudPayments.
- Перейдите в раздел Сайты и выберите ваш сайт.
- Откройте Настройки сайта (или Настройки уведомлений).
- В панели настроек вы увидите список типов уведомлений (
Check,Pay,Fail,Confirm,Refundи др.). - Для каждого нужного типа событий (например,
Pay— успешный платеж):- Вставьте ваш публичный адрес из TunnelHunt с нужным путем:
https://sleepy-owl.tunnelhunt.ru/webhook/cloudpayments - Выберите метод отправки: POST.
- Выберите формат запроса: JSON.
- Вставьте ваш публичный адрес из TunnelHunt с нужным путем:
- Сохраните изменения.
Шаг 4: Тестирование и Request Replay в TunnelHunt
Инициируйте тестовый платеж в виджете CloudPayments. Система отправит POST-запрос на ваш туннель, и Flask-сервер выведет в консоль информацию об успешной оплате.
Если в процессе обработки заказа на вашей стороне произошел сбой (например, ошибка записи в базу данных), вам не нужно повторно открывать форму оплаты.
Перейдите в личный кабинет TunnelHunt в раздел Logs:
- Найдите упавший запрос к
/webhook/cloudpayments. - Нажмите кнопку Replay (Повторить запрос).
- TunnelHunt повторит запрос к вашему локальному серверу с точно таким же телом и заголовком
Content-HMAC-SHA256, что позволит вам быстро отладить и исправить ошибку.
Готовы запустить свой первый туннель?
Начните использовать TunnelHunt бесплатно уже сегодня и откройте доступ к локальному серверу всего одной командой.
Зарегистрироваться бесплатно →По теме

Платёжные вебхуки на localhost: ЮKassa, Т-Банк, Robokassa и CloudPayments
7 сентября 2025 г.
Как проверить доставку платёжного вебхука на локальный сервер: HTTPS-туннель, выбор инструкции провайдера, подпись, повтор и диагностика HTTP-ответов.

Локальное тестирование вебхуков ЮKassa (YooKassa) через TunnelHunt
22 июня 2026 г.
Пошаговый гайд по настройке уведомлений ЮKassa (YooKassa) на локальном сервере. Как пробросить порт, прописать URL в личном кабинете и проверить цифровую подпись.

Robokassa ResultURL на localhost: подпись, OK и повтор уведомления
22 июня 2026 г.
Проверяем ResultURL Robokassa локально: Flask, подпись MD5 с Password 2 и Shp_, сумма счёта, ответ OK и диагностика через HTTPS-туннель.

Как открыть localhost в интернете: публичный HTTPS через SSH
11 сентября 2026 г.
Пошагово открываем локальный сайт из интернета без настройки роутера: SSH-туннель, проверка ссылки, Docker, Vite и диагностика ошибок.