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

Webhooks

Что такое Webhook?

Webhook (веб-перехватчик) — это механизм, который позволяет платформе Mesilat автоматически уведомлять ваш сервер о важных событиях в режиме реального времени. Когда происходит событие (например, успешная оплата), платформа отправляет HTTP POST запрос на указанный вами URL с данными о событии.

Данные в Webhook

При отправке webhook в теле запроса передаются:

  • additional_fields — дополнительные поля, которые были настроены в настройках продукта и заполнены покупателем на странице оплаты (checkout)
  • metadata — метаданные, которые были переданы при создании payment link (только для payment links)
  • Информация о заказе, покупателе и платеже

Пример данных webhook

{
  "uuid": "b9c3e992",
  "amount": 500,
  "total_amount": 460,
  "currency": "RUB",
  "commission": 40,
  "exchange_rate": 1,
  "created_at": 1759919382,
  "metadata": [],
  "additional_fields": {
    "hidden_0": {
      "text": "platform_product_id=115123584",
      "type": "hidden",
      "value": null
    }
  },
  "customer_phone": "+35796612353",
  "customer_name": "Emma S.",
  "customer_email": "[email protected]",
  "product_id": 141,
  "product_title": "Custom Service",
  "product_type": "CustomService",
  "trigger_type": "auto"
}

Описание полей

Информация о транзакции

Поле Тип Описание
uuid string Уникальный идентификатор транзакции. Используйте для обеспечения идемпотентности
amount number Полная сумма платежа в основных единицах валюты (например, 20 EUR)
total_amount number Итоговая сумма после вычета комиссии платформы
commission number Размер комиссии платформы, удержанной с транзакции
currency string Валюта платежа. Возможные значения: EUR, USD, RUB
exchange_rate number Курс обмена валюты (если применяется конвертация)
created_at integer Время создания транзакции в формате Unix timestamp

Данные покупателя

Поле Тип Описание
customer_name string Имя покупателя, указанное при оформлении заказа
customer_email string Email покупателя
customer_phone string Телефон покупателя в международном формате

Информация о продукте

Поле Тип Описание
product_id integer Уникальный идентификатор продукта
product_title string Название продукта
product_type string Тип продукта (см. таблицу ниже)

Дополнительные данные

Поле Тип Описание
additional_fields object/array Дополнительные поля, настроенные в продукте и заполненные покупателем на checkout. Поля создаются в интерфейсе платформы (см. изображение ниже) и передаются в webhook. См. подробное описание структуры ниже
metadata object/array Метаданные, переданные при создании payment link. Доступны только для payment links. Может содержать любые пользовательские данные или быть пустым массивом []
trigger_type string Тип триггера отправки webhook: auto (автоматический при успешной оплате) или manual (тестовое событие)

Создание additional_fields

Дополнительные поля настраиваются в интерфейсе платформы Mesilat в разделе "Информация о клиенте" конкретного продукта:

Настройка дополнительных полей

В интерфейсе вы можете:

  1. Создать дополнительные поля различных типов
  2. Настроить, какие поля обязательны для заполнения

Все заполненные клиентом поля во время оформления заказа будут переданы в webhook в разделе additional_fields.

Формат additional_fields

Поле additional_fields может иметь два формата:

1. Пустой массив (если дополнительные поля не настроены):

"additional_fields": []

2. Объект с полями (если дополнительные поля настроены и заполнены):

"additional_fields": {
  "field_name": {
    "text": "значение или описание поля",
    "type": "тип поля (text, email, phone, hidden и т.д.)",
    "value": "значение поля или null"
  }
}

Пример с заполненными полями:

"additional_fields": {
  "hidden_0": {
    "text": "platform_product_id=115123584",
    "type": "hidden",
    "value": null
  },
  "text_1": {
    "text": "Additional information",
    "type": "text",
    "value": "Additional information"
  },
  "checkbox_2": {
    "text": "I agree to terms",
    "type": "checkbox",
    "value": "true"
  },
  "select_3": {
    "text": "Premium",
    "type": "select",
    "value": "Premium"
  }
}

Каждое поле в additional_fields содержит: - text — текстовое значение или описание поля - type — тип поля (см. таблицу возможных типов ниже) - value — заполненное значение поля или null

Возможные типы additional_fields

Тип Описание
text Текстовое поле
checkbox Чекбокс (флажок)
radio Радиокнопка (выбор одного варианта)
select Выпадающий список
link Поле для ссылки/URL
hidden Скрытое поле

Типы продуктов (product_type)

Значение Описание
DigitalDownload Цифровой продукт для скачивания (файлы, документы, медиа)
CustomService Индивидуальная услуга
RecurringMembership Подписка с регулярными платежами

Безопасность Webhook

Webhook Key

Каждый webhook подписывается специальным ключом webhook_key, который передается в заголовке запроса webhook-key. Это позволяет вам убедиться, что запрос действительно пришел от платформы Mesilat.

Заголовок запроса:

webhook-key: your_webhook_key_here

Пример проверки подписи:

// PHP
$webhookKey = $_SERVER['HTTP_WEBHOOK_KEY'] ?? '';
$expectedKey = getenv('MESILAT_WEBHOOK_KEY');

if ($webhookKey !== $expectedKey) {
    http_response_code(401);
    exit('Invalid webhook key');
}
// Node.js
const webhookKey = req.headers['webhook-key'];
const expectedKey = process.env.MESILAT_WEBHOOK_KEY;

if (webhookKey !== expectedKey) {
  return res.status(401).send('Invalid webhook key');
}
# Python
webhook_key = request.headers.get('webhook-key')
expected_key = os.getenv('MESILAT_WEBHOOK_KEY')

if webhook_key != expected_key:
    return Response('Invalid webhook key', status=401)

Настройка Webhook

Webhook настраивается в личном кабинете платформы Mesilat:

Настройка Webhook

Шаги настройки:

  1. Включите webhook — активируйте функцию отправки webhook уведомлений
  2. Укажите ваш URL webhook — введите полный URL адрес вашего сервера, который будет принимать уведомления (например: https://webhook-test.com/a6f72e919ce3f0c26f4a12cfa45c9a7a)
  3. Сгенерируйте и сохраните себе ключ webhook — создайте уникальный ключ для подписи запросов и сохраните его в безопасном месте
  4. Нажмите "Сохранить" — примените настройки
  5. Отправьте тестовое событие на ваш webhook — проверьте работоспособность интеграции, отправив тестовый запрос

Повторные попытки отправки

Платформа Mesilat автоматически повторяет отправку webhook в случае неудачи (если ваш сервер не вернул код ответа 200).

Механизм повторных попыток:

Всего выполняется до 10 попыток отправки с увеличивающимися интервалами:

Попытка Интервал
1 Сразу
2 1 минута
3 5 минут
4 10 минут
5 20 минут
6 30 минут
7 1 час
8 1 час
9 1 час
10 1 час

Условия успешной доставки:

✅ Ваш сервер должен вернуть HTTP код ответа 200 для подтверждения получения webhook

❌ Любые другие коды (4xx, 5xx) или таймаут будут считаться неудачной попыткой

Уведомление о неудаче

Если после 10 попыток webhook так и не был доставлен, на ваш email придет уведомление с информацией о проблеме. Это позволит вам оперативно отреагировать на сбой в интеграции.

Требования к обработке Webhook

Быстрый ответ

Ваш endpoint должен отвечать быстро (в течение 5-10 секунд). Если обработка данных требует времени, используйте асинхронную обработку:

  1. Получите webhook
  2. Сохраните данные в очередь/базу данных
  3. Сразу верните код 200
  4. Обработайте данные в фоновом режиме

Идемпотентность

Webhook может быть доставлен несколько раз (при повторных попытках). Убедитесь, что повторная обработка одного и того же события не приведет к дублированию действий. Используйте uuid транзакции для проверки уникальности.

Пример обработчика

// PHP (Laravel)
Route::post('/webhooks/mesilat', function (Request $request) {
    // Проверка webhook key
    $webhookKey = $request->header('webhook-key');
    if ($webhookKey !== config('mesilat.webhook_key')) {
        return response('Unauthorized', 401);
    }

    // Получение данных
    $data = $request->all();
    $uuid = $data['uuid'];

    // Проверка идемпотентности
    if (Order::where('transaction_uuid', $uuid)->exists()) {
        return response('OK', 200); // Уже обработано
    }

    // Добавление в очередь для обработки
    ProcessWebhookJob::dispatch($data);

    // Быстрый ответ
    return response('OK', 200);
});
// Node.js (Express)
app.post('/webhooks/mesilat', async (req, res) => {
  // Проверка webhook key
  const webhookKey = req.headers['webhook-key'];
  if (webhookKey !== process.env.MESILAT_WEBHOOK_KEY) {
    return res.status(401).send('Unauthorized');
  }

  const data = req.body;
  const uuid = data.uuid;

  // Проверка идемпотентности
  const exists = await Order.findOne({ transactionUuid: uuid });
  if (exists) {
    return res.status(200).send('OK'); // Уже обработано
  }

  // Добавление в очередь
  await queue.add('processWebhook', data);

  // Быстрый ответ
  res.status(200).send('OK');
});
# Python (Flask)
@app.route('/webhooks/mesilat', methods=['POST'])
def webhook():
    # Проверка webhook key
    webhook_key = request.headers.get('webhook-key')
    if webhook_key != os.getenv('MESILAT_WEBHOOK_KEY'):
        return Response('Unauthorized', status=401)

    data = request.json
    uuid = data['uuid']

    # Проверка идемпотентности
    if Order.query.filter_by(transaction_uuid=uuid).first():
        return Response('OK', status=200)  # Уже обработано

    # Добавление в очередь
    process_webhook.delay(data)

    # Быстрый ответ
    return Response('OK', status=200)

Отладка

Логирование

Рекомендуется логировать все входящие webhook для отладки:

// PHP
Log::info('Webhook received', [
    'uuid' => $data['uuid'],
    'product_id' => $data['product_id'],
    'amount' => $data['amount'],
    'trigger_type' => $data['trigger_type'],
    'data' => $data
]);

Тестирование

Используйте функцию "Отправить тестовое событие" в настройках webhook для проверки интеграции перед запуском в продакшн.