Endpoint (API v2): Регистрация вебхука уведомлений

ℹ️ EasyPay API v2. Это ручка второго поколения EasyPay API (база https://api.appsign.me), пришедшего на смену legacy-API v1 (https://n8n.thenextgen.store/webhook/*). Отличия v2 от v1: авторизация заголовком X-Partner-Api-Key, плоское тело запроса, идемпотентность через опциональный client_token (полный ключ собирает сервер), коды ошибок — в UPPER_CASE.

Зачем это нужно

Зарегистрировать ваш собственный HTTPS-endpoint как адрес, куда EasyPay шлёт server-to-server уведомления о Stripe-событиях (успешные оплаты, подписки, рефанды, диспуты). EasyPay будет POST'ить события туда. Можно указать live-URL и/или test-URL — как минимум один обязателен.

При регистрации вы получаете секрет подписи (whsec_…), которым проверяете, что вебхук действительно пришёл от EasyPay (см. Webhook EasyPay: проверка подписи).

Ручка идемпотентна (get-or-create) и всегда возвращает текущий секрет. Первый вызов создаёт вебхук и минтит секрет (secret_status: "issued"); повторный вызов возвращает тот же текущий секрет (secret_status: "returned"). Потеряли секрет — просто вызовите register ещё раз, он его вернёт. Чтобы сменить секрет (утечка / плановая ротация) — используйте rotate_partner_webhook_secret.

Как подключиться

  1. Запросите API-ключ у вашего менеджера EasyPay (или скопируйте в мини-аппе, «Show key» на первом шаге онбординга).

  2. Менеджер активирует разрешение webhook_config для вашего аккаунта.

Endpoint

POST https://api.appsign.me/register-partner-notifications-webhook
Content-Type: application/json
X-Partner-Api-Key: ваш-api-ключ

Формат запроса

{
  "live_url": "https://partner.example.com/easypay-webhook",
  "test_url": "http://localhost:3000/easypay-webhook",
  "client_token": "setup-1"
}

Параметры:

Параметр

Обязательный

Описание

live_url

Один из двух

Боевой URL для событий. HTTPS обязателен, не localhost.

test_url

Один из двух

Тестовый URL. Допускается http:// и https:// (для локальной разработки).

client_token

Нет

Ваш идемпотентный токен. Не передали — сервер дедупит по URL'ам. register — get-or-create, поэтому повтор в любом случае вернёт текущий секрет.

Как минимум один из live_url / test_url обязателен. У test и liveразные секреты; зарегистрировав обе среды, вы получите два секрета.

Формат ответа

Успешный ответ (200)

{
  "success": true,
  "registered": [
    {
      "environment": "live",
      "webhook_url": "https://partner.example.com/easypay-webhook",
      "secret_status": "issued",
      "signing_secret": "whsec_live_9f2c8a1b…"
    }
  ]
}

Поле

Описание

signing_secret

Текущий секрет подписи (whsec_live_… / whsec_test_…) для этой среды. Присутствует всегда. Сохраните его в надёжном месте.

secret_status

"issued" — секрет сминчен на этом вызове (впервые); "returned" — секрет уже существовал и возвращён повторно (get-or-create).

environment / webhook_url

Среда и зарегистрированный URL.

Ошибки

Все ошибки возвращаются с HTTP 200 + полем success: false и error_code. Проверяйте success, а не HTTP-статус.

error_code

Когда срабатывает

INVALID_INPUT

Ни один URL не передан; live_url не https:// или указывает на localhost/.local; невалидный URL; URL длиннее 2048 символов.

AUTH_REQUIRED / INVALID_API_KEY

Не передан или невалиден API-ключ.

PERMISSION_DENIED

У ключа нет разрешения webhook_config. Запросите его у менеджера EasyPay.

INTERNAL_ERROR

Внутренний сбой EasyPay. Команда заботы уведомлена.

После регистрации

  • Проверяйте подпись каждого входящего вебхука — сниппеты Node.js / Python в гайде.

  • Потеряли секрет? Вызовите register ещё раз — он вернёт текущий.

  • Сменить секрет (утечка / расписание)? Вызовите rotate_partner_webhook_secret.

Пример на Python

import urllib.request
import json

url = "https://api.appsign.me/register-partner-notifications-webhook"
payload = {
    "live_url": "https://partner.example.com/easypay-webhook",
    "client_token": "setup-1",
}

req = urllib.request.Request(
    url,
    data=json.dumps(payload).encode("utf-8"),
    headers={"Content-Type": "application/json", "X-Partner-Api-Key": "ваш-api-ключ"},
    method="POST",
)

with urllib.request.urlopen(req) as resp:
    result = json.loads(resp.read().decode("utf-8"))

if result.get("success"):
    for r in result["registered"]:
        print(r["environment"], "→ секрет:", r["signing_secret"], f"({r['secret_status']})")
else:
    print("Ошибка:", result.get("error_code"), "—", result.get("error_message"))

Пример на cURL

curl -X POST "https://api.appsign.me/register-partner-notifications-webhook" \
  -H "Content-Type: application/json" \
  -H "X-Partner-Api-Key: ваш-api-ключ" \
  -d '{
    "live_url": "https://partner.example.com/easypay-webhook",
    "client_token": "setup-1"
  }'

См. также