API для приёма платежей и уведомлений
Создавайте инвойсы, отправляйте клиента на хостинговую страницу оплаты и получайте финальный статус через callback с HMAC-подписью.
Базовый URL
Тела и ответы — UTF-8. JSON API принимает только application/json. Браузерные запросы к API идут на тот же origin.
Обзор
Merchant API принимает подписанные запросы и возвращает ссылку на хостинговую страницу оплаты. Финальный статус приходит на ваш callback.
Авторизация
Создайте API-ключ в кабинете (Настройки → API-ключи). Каждый запрос к Merchant API подписывается HMAC-SHA256.
Обязательные заголовки
X-API-KEYПубличный api_key из кабинетаX-TIMESTAMPUnix-секунды или RFC3339 UTC (окно ~5 минут)X-NONCEУникальная строка ≥ 8 символов (replay protection; не переиспользовать)X-SIGNATUREhex(HMAC-SHA256(secret_key, canonical_string))Idempotency-KeyУникальный ключ идемпотентности запросаContent-Typeapplication/json (для POST с телом; для GET не нужен)METHOD
PATH
X-TIMESTAMP
X-NONCE
SHA256_HEX(body)POST
/api/v1/merchant/test-secure
1716883200
8d52f2e4f39f4f45a567a3b6e9b4be11
44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8asignature = hex(HMAC_SHA256(secret_key, canonical_string))PATH — путь без хоста и query (например /api/v1/invoice/create). METHOD — в верхнем регистре. Хешируйте и подписывайте сырые байты body как уходят в сеть (без pretty-print). secret_key храните только на сервере, не в браузере и не в клиентских логах. Окно timestamp / TTL nonce — около 5 минут; nonce одноразовый.
Создать инвойс
POST /api/v1/invoice/create → 201
Создаёт инвойс в статусе pending и возвращает pay_url для оплаты.
- amount — целое в минимальных единицах (10000 = 100.00 RUB), диапазон 1…30000000.
- order_id обязателен и уникален у мерчанта (иначе 409 ORDER_ALREADY_EXISTS).
- description рекомендуется (сохраняется в инвойсе), сервером как обязательное не валидируется.
- project_url и redirect_url обязательны в запросе или в дефолтах мерчанта; fail_redirect_url / callback_url опциональны.
- TTL оплаты по умолчанию — 30 минут (expires_at).
- Если у мерчанта включён IP allowlist — запрос с чужого IP → VALIDATION_ERROR.
- Требуется полный набор HMAC-заголовков и Idempotency-Key. Только HTTPS на проде.
- Успешный ответ — HTTP 201.
{
"amount": 10000,
"currency": "RUB",
"order_id": "order-1001",
"description": "Оплата заказа #1001",
"project_url": "https://shop.example",
"redirect_url": "https://shop.example/success",
"fail_redirect_url": "https://shop.example/fail",
"callback_url": "https://shop.example/payment/callback"
}{
"status": "success",
"data": {
"invoice_id": "4db8a776-6f90-4eaa-8184-8ea4b4ee755f",
"pay_url": "https://aggrepay.ai/checkout/4db8a776-6f90-4eaa-8184-8ea4b4ee755f",
"payment_status": "pending"
}
}curl -X POST 'https://aggrepay.ai/api/v1/invoice/create' \
-H 'Content-Type: application/json' \
-H 'X-API-KEY: YOUR_API_KEY' \
-H 'X-TIMESTAMP: 1716883200' \
-H 'X-NONCE: 8d52f2e4f39f4f45a567a3b6e9b4be11' \
-H 'X-SIGNATURE: YOUR_HMAC_HEX' \
-H 'Idempotency-Key: create-order-1001' \
-d '{
"amount": 10000,
"currency": "RUB",
"order_id": "order-1001",
"description": "Оплата заказа #1001"
}'Получить инвойс
GET /api/v1/invoice/{id} → 200
Возвращает текущее состояние инвойса по UUID.
- Для GET тело пустое: SHA256 пустого body = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.
- PATH в канонике — полный путь, например /api/v1/invoice/4db8a776-…
- Опционально в ответе: provider_id, provider_account_id, referral_amount, referrer_merchant_id.
{
"status": "success",
"data": {
"invoice_id": "4db8a776-6f90-4eaa-8184-8ea4b4ee755f",
"merchant_id": "174a86e3-e4eb-43dc-9000-ee83f0b4d536",
"order_id": "order-1001",
"amount": 10000,
"currency": "RUB",
"description": "Оплата заказа #1001",
"status": "pending",
"pay_url": "https://aggrepay.ai/checkout/4db8a776-6f90-4eaa-8184-8ea4b4ee755f",
"project_url": "https://shop.example",
"redirect_url": "https://shop.example/success",
"fail_redirect_url": "https://shop.example/fail",
"callback_url": "https://shop.example/payment/callback",
"expires_at": "2026-10-08T22:00:00Z",
"created_at": "2026-10-08T21:00:00Z",
"updated_at": "2026-10-08T21:00:00Z"
}
}curl -X GET 'https://aggrepay.ai/api/v1/invoice/4db8a776-6f90-4eaa-8184-8ea4b4ee755f' \
-H 'X-API-KEY: YOUR_API_KEY' \
-H 'X-TIMESTAMP: 1716883200' \
-H 'X-NONCE: unique-nonce-001' \
-H 'X-SIGNATURE: YOUR_HMAC_HEX' \
-H 'Idempotency-Key: get-invoice-001'История статусов
GET /api/v1/invoice/{id}/history → 200
Хронология смен статуса инвойса (источник и причина).
- Полезно для сверки и поддержки: кто и когда перевёл инвойс в success/failed/expired.
- Типичные source: system (создание), provider (webhook / старт оплаты).
{
"status": "success",
"data": [
{
"old_status": null,
"new_status": "pending",
"source": "system",
"reason": "invoice_created",
"created_at": "2026-10-08T21:00:00Z"
},
{
"old_status": "pending",
"new_status": "success",
"source": "provider",
"reason": "webhook:evt_abc123",
"created_at": "2026-10-08T21:02:11Z"
}
]
}curl -X GET 'https://aggrepay.ai/api/v1/invoice/4db8a776-6f90-4eaa-8184-8ea4b4ee755f/history' \
-H 'X-API-KEY: YOUR_API_KEY' \
-H 'X-TIMESTAMP: 1716883200' \
-H 'X-NONCE: unique-nonce-002' \
-H 'X-SIGNATURE: YOUR_HMAC_HEX' \
-H 'Idempotency-Key: history-001'Проверка подписи
POST /api/v1/merchant/test-secure → 200
Прогоняет цепочку API key + HMAC + timestamp + nonce + idempotency + rate limit без создания платежа.
- Используйте после выдачи ключей, чтобы убедиться, что подпись собирается верно.
- В примере body = {} → SHA256 = 44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a.
- Пустое body (GET без тела) → SHA256 = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.
{}{
"status": "success",
"data": {
"merchant_id": "174a86e3-e4eb-43dc-9000-ee83f0b4d536",
"message": "merchant api security ok"
}
}curl -X POST 'https://aggrepay.ai/api/v1/merchant/test-secure' \
-H 'Content-Type: application/json' \
-H 'X-API-KEY: YOUR_API_KEY' \
-H 'X-TIMESTAMP: 1716883200' \
-H 'X-NONCE: 8d52f2e4f39f4f45a567a3b6e9b4be11' \
-H 'X-SIGNATURE: YOUR_HMAC_HEX' \
-H 'Idempotency-Key: test-secure-001' \
-d '{}'Доставка событий
Это не входящий маршрут Aggrepay. После terminal-статуса (success, failed, expired, refunded, chargeback) сервис шлёт HTTP POST на callback_url инвойса (или дефолт мерчанта).
- Перед доверием к payload проверьте `X-SIGNATURE`; невалидные/без подписи — игнорируйте.
- Ответьте кодом 2xx, чтобы подтвердить доставку.
- При не-2xx — повтор с backoff (5с → 60с), до 10 попыток, затем dead-letter.
- Песочница (sandbox) доступна только в админке при включённом флаге — это не публичный Merchant-метод.
Заголовки callback
Content-Typeapplication/jsonX-TIMESTAMPRFC3339 UTCX-SIGNATUREhex(HMAC-SHA256(secret, canonical))X-SIGNATURE-VERSIONv1Формат payload
{
"invoice_id": "4db8a776-6f90-4eaa-8184-8ea4b4ee755f",
"order_id": "order-1001",
"amount": 10000,
"currency": "RUB",
"status": "success",
"provider": "mulenpay",
"provider_payment_id": "prov_abc123",
"timestamp": "2026-10-08T21:02:11Z"
}Проверка подписи
Секрет — тот же secret_key активного API-ключа. Соберите канонику по сырым байтам body и сравните с X-SIGNATURE (constant-time). Статусу доверяйте только после совпадения подписи.
POST
/merchant/callback
{X-TIMESTAMP}
{SHA256_HEX(body)}signature = hex(HMAC_SHA256(secret_key, canonical_string))Страница оплаты
pay_url ведёт на https://aggrepay.ai/checkout/{invoice_id}. Клиент выбирает метод оплаты (СБП и др.). После успеха — redirect на success URL, при ошибке — на fail URL (если задан).
Статусы инвойса
pendingСоздан, ожидает оплатуprocessingПлатёж в обработке у провайдераsuccessУспешно оплаченfailedОплата не прошлаexpiredИстёк срок оплатыrefundedВозвратchargebackЧарджбекСуммы и валюты
- amount — целое в minor units: 10000 = 100.00 RUB / USD / EUR.
- Валюты:
RUB,USD,EUR. - Глобальный диапазон по умолчанию: от 1 до 30 000 000 minor (0.01 … 300 000 major). У мерчанта могут быть свои лимиты.
- Срок жизни инвойса (TTL) по умолчанию — 30 минут с момента создания.
Коды ошибок
Формат: { "status": "error", "code": "...", "message": "..." }
MISSING_API_KEY401Нет заголовка X-API-KEYINVALID_API_KEY401Ключ не найден или отключёнAPI_KEY_REVOKED401Ключ отозванMISSING_SIGNATURE401Нет X-SIGNATUREINVALID_SIGNATURE401Подпись не совпала — проверьте body, PATH и secret_keyINVALID_TIMESTAMP400Некорректный или просроченный X-TIMESTAMPREPLAY_DETECTED400Nonce уже использован / слишком короткийMISSING_IDEMPOTENCY_KEY400Нет Idempotency-KeyIDEMPOTENCY_CONFLICT400Тот же ключ с другим телом запросаRATE_LIMIT_EXCEEDED429Превышен лимит запросовMERCHANT_BLOCKED403Мерчант заблокированMERCHANT_NOT_ACTIVE403Мерчант не в статусе activeORDER_ALREADY_EXISTS409order_id уже существует у этого мерчантаVALIDATION_ERROR400Некорректное тело/URL/сумма или IP не в allowlistNOT_FOUND404Инвойс не найден