# 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: проверка подписи](https://docs.thenextgen.store/s/635a43c1-37fa-463b-bc7e-7ede7884fce2/doc/webhook-easypay-proverka-podpisi-YS2uy0j2It)).

> ✅ **Ручка идемпотентна (get-or-create) и всегда возвращает текущий секрет.** Первый вызов создаёт вебхук и минтит секрет (`secret_status: "issued"`); повторный вызов **возвращает тот же текущий секрет** (`secret_status: "returned"`). Потеряли секрет — просто вызовите register ещё раз, он его вернёт. Чтобы **сменить** секрет (утечка / плановая ротация) — используйте [rotate_partner_webhook_secret](https://docs.thenextgen.store/s/635a43c1-37fa-463b-bc7e-7ede7884fce2/doc/endpoint-api-v2-rotaciya-sekreta-podpisi-vebhukov-WRlr8kxNX2).

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


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-ключ
```

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

```json
{
  "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)

```json
{
  "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 в [гайде](https://docs.thenextgen.store/s/635a43c1-37fa-463b-bc7e-7ede7884fce2/doc/webhook-easypay-proverka-podpisi-YS2uy0j2It).
* **Потеряли секрет?** Вызовите register ещё раз — он вернёт текущий.
* **Сменить секрет** (утечка / расписание)? Вызовите `rotate_partner_webhook_secret`.

## Пример на Python

```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

```bash
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"
  }'
```

## См. также

* [Webhook EasyPay: проверка подписи](https://docs.thenextgen.store/s/635a43c1-37fa-463b-bc7e-7ede7884fce2/doc/webhook-easypay-proverka-podpisi-YS2uy0j2It) — как проверить HMAC-подпись входящего вебхука.