Исходящие webhooks (PlatParts → ваш сервер)
Способ A из [обзора](./: без PHP‑модуля на zapex, только HTTPS endpoint у вас.
Где настроить
Модули интеграций → Подключения модулей → редактирование подключения → вкладка Исходящие webhooks.
| Поле | Описание |
|---|---|
| URL | HTTPS endpoint (на prod) |
| Секрет | Для X-Integration-Signature |
| Список хуков | Конкретные имена или пусто = все события, которые проходят фильтр endpoint |
| Активность | Выключенный endpoint не получает POST |
Подключение должно быть активным и соответствовать точке события (или «для всех»).
Тело запроса
POST https://your-service.example/hooks/zapex
Content-Type: application/json
X-Integration-Signature: <hmac>
{
"hook": "order.created",
"payload": {
"id": 123,
"pickup_point_id": 1,
"status_code": "order.created",
"items": []
},
"sent_at": "2026-05-29T12:00:00+00:00"
}
Поля payload — см. Хуки и события.
Подпись
HMAC-SHA256 от канонического JSON объекта { hook, payload, sent_at } (ключи отсортированы рекурсивно).
PHP (проверка на вашей стороне):
use App\Integrations\Support\IntegrationJsonSigner; // или скопируйте алгоритм
$body = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
$expected = IntegrationJsonSigner::sign($body, $secret);
if (! hash_equals($expected, $_SERVER['HTTP_X_INTEGRATION_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
Python (эквивалент canonical):
import hashlib, hmac, json
def canonical(obj):
if isinstance(obj, dict):
return {k: canonical(obj[k]) for k in sorted(obj)}
if isinstance(obj, list):
return [canonical(x) for x in obj]
return obj
def sign(body: dict, secret: str) -> str:
raw = json.dumps(canonical(body), ensure_ascii=False, separators=(',', ':'))
return hmac.new(secret.encode(), raw.encode(), hashlib.sha256).hexdigest()
Таймаут по умолчанию 15 с (INTEGRATION_OUTBOUND_TIMEOUT). Тяжёлую работу — в свою очередь после 200 OK.
Очередь и повторы
- Очередь:
integrations.outbound - Попытки:
INTEGRATION_OUTBOUND_TRIES(по умолчанию 3) - Нужен queue worker на этой очереди
Без воркера задачи копятся; handler в hooks.php при этом может работать, если у него свой воркер.
Политика URL
| URL | Поведение |
|---|---|
Не HTTPS (без INTEGRATION_OUTBOUND_ALLOW_HTTP) |
Job падает, retry |
localhost, 127.0.0.1, private IP |
Только при INTEGRATIONS_DEBUG=true |
| Некорректный URL | Ошибка, не «тихий» skip |
Независимость от hooks.php
Outbound настраивается только в админке подключения. Файл hooks.php для outbound не обязателен.
Пустой список хуков в endpoint = отправлять все события, для которых сработала доставка (фильтр по подписке endpoint пустой).