Merchant API v1

Документация Adsrek Pay API

Полное руководство по созданию счетов, HMAC-подписям, проверке статусов, callback-уведомлениям и внутренним выплатам на AR-кошельки.

HTTPSPOST JSONHMAC-SHA256UTF-8
У вас пока нет сайта. Документация доступна с демонстрационными значениями. Для реальных ключей сначала добавьте сайт.
01

Быстрый старт

Минимальный рабочий сценарий приёма оплаты.

1Создайте сайт и получите SHOP ID, API KEY и SECRET KEY.
2На своём сервере сформируйте HMAC-подпись и создайте счёт.
3Перенаправьте клиента на payment_url.
4После оплаты проверьте подписанный callback или статус через API.
Базовый адрес:https://adsrekpay.com
Важно: переход клиента на Success URL сам по себе не подтверждает оплату. Засчитывайте заказ только после статуса paid и проверки подписи.
02

Общие требования

Формат запросов и поддерживаемые значения.

Метод и формат

Все методы принимают только POST. Рекомендуемый заголовок: Content-Type: application/json. Также принимается обычный POST-массив.

Размер запроса

Максимальный размер тела запроса — 65 536 байт. Превышение возвращает HTTP 413.

Валюты

RUB, USD, EUR, USDT.

Точность суммы

RUB, USD, EUR — 2 знака после точки. USDT — 8 знаков. Перед подписью сумма нормализуется сервером.

Срок счёта

Счёт действует 24 часа с момента создания. В ответе приходит Unix timestamp expires_at.

Кодировка

Используйте UTF-8. Поля order_id и description очищаются и ограничиваются по длине.

03

Авторизация и HMAC-SHA256

Каждый запрос подписывается SECRET KEY выбранного сайта.

В запросе всегда передаются shop_id, api_key и 64-символьный шестнадцатеричный sign. SECRET KEY используется только для вычисления подписи и никогда не отправляется в API.

Создание счётаcreate|SHOP_ID|API_KEY|ORDER_ID|AMOUNT|CURRENCY
Проверка статусаstatus|SHOP_ID|API_KEY|ORDER_ID
Выплатаpayout|SHOP_ID|API_KEY|ORDER_ID|AMOUNT|CURRENCY|TARGET
PHP: вычисление подписи
function adsrekSign(string $canonical, string $secretKey): string
{
    return hash_hmac('sha256', $canonical, $secretKey);
}

$amount = number_format(10, 2, '.', '');
$canonical = 'create|1001|aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|ORDER-1001|' . $amount . '|RUB';
$sign = adsrekSign($canonical, 'YOUR_SECRET_KEY');
Нормализация: для суммы 10 RUB подписывается строка 10.00, а для 1 USDT — 1.00000000. Валюта передаётся в верхнем регистре.
04

Создание счёта

POST https://adsrekpay.com/api/pay/create.php

ПолеОбязательноеОписание
shop_idДаID сайта из кабинета.
api_keyДаПубличный API KEY сайта.
order_idДаУникальный ID заказа в пределах сайта, до 100 символов.
amountДаСумма не меньше 0.01.
currencyДаRUB, USD, EUR или USDT.
descriptionНетОписание заказа, до 255 символов.
callback_urlНетПубличный HTTPS URL. Переопределяет адрес сайта для этого счёта.
success_urlНетHTTPS URL возврата после успешной оплаты.
fail_urlНетHTTPS URL возврата при отмене или ошибке.
signДаHMAC-SHA256 канонической строки.
Запрос JSON
{
  "shop_id": 1001,
  "api_key": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "order_id": "ORDER-1001",
  "amount": "10.00",
  "currency": "RUB",
  "description": "Оплата заказа ORDER-1001",
  "callback_url": "https://site.ru/payment/callback",
  "success_url": "https://site.ru/payment/success",
  "fail_url": "https://site.ru/payment/fail",
  "sign": "HMAC_SHA256_HEX"
}
Успешный ответ
{
  "ok": true,
  "invoice_id": 1501,
  "order_id": "ORDER-1001",
  "status": "new",
  "amount": "10.00",
  "currency": "RUB",
  "payment_url": "https://adsrekpay.com/merchant/invoice.php?id=TOKEN",
  "expires_at": 1785704400
}
Идемпотентность: повторный запрос с тем же order_id, суммой и валютой вернёт существующий счёт. Если сумма или валюта отличаются, API вернёт ORDER_ID_CONFLICT.
05

Проверка статуса счёта

POST https://adsrekpay.com/api/pay/status.php

Запрос
{
  "shop_id": 1001,
  "api_key": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "order_id": "ORDER-1001",
  "sign": "HMAC_SHA256_HEX"
}
Ответ
{
  "ok": true,
  "invoice": {
    "id": "1501",
    "order_id": "ORDER-1001",
    "amount": "10.00",
    "currency": "RUB",
    "status": "paid",
    "created_at": "1785618000",
    "paid_at": "1785618125"
  }
}

Проверяйте одновременно status, amount, currency и order_id. Не считайте заказ оплаченным по одному только URL возврата.

06

Callback / webhook

Уведомление отправляется после успешной оплаты счёта.

Формат

POST application/x-www-form-urlencoded.

Успешный ответ

Любой HTTP-код от 200 до 299 считается успешной доставкой.

Повторы

До 5 попыток, с интервалом не менее 5 минут, пока не получен 2xx.

Сетевая защита

Только публичный HTTPS, проверка SSL, без перенаправлений. Таймаут соединения 5 секунд, общий — 10 секунд.

Поля callback
invoice_id=1501
shop_id=1001order_id=ORDER-1001
amount=10.00
currency=RUB
status=paid
paid_at=1785618125
sign=HMAC_SHA256_HEX
Строка подписи
invoice_id|shop_id|order_id|amount|currency|status

1501|1001|ORDER-1001|10.00|RUB|paid
PHP: безопасный обработчик callback
<?php
$secretKey = getenv('ADSREK_PAY_SECRET');
$data = $_POST;

$required = ['invoice_id','shop_id','order_id','amount','currency','status','sign'];
foreach ($required as $field) {
    if (!isset($data[$field])) {
        http_response_code(400);
        exit('MISSING_FIELD');
    }
}

$canonical = implode('|', [
    (int)$data['invoice_id'],
    (int)$data['shop_id'],
    (string)$data['order_id'],
    (string)$data['amount'],
    (string)$data['currency'],
    (string)$data['status'],
]);
$expected = hash_hmac('sha256', $canonical, $secretKey);

if (!hash_equals($expected, strtolower((string)$data['sign']))) {
    http_response_code(401);
    exit('BAD_SIGNATURE');
}

// Найдите заказ по order_id и заблокируйте строку в транзакции БД.
// Повторный callback для уже оплаченного заказа должен вернуть 200 без повторного начисления.
if ($data['status'] === 'paid') {
    // Дополнительно сравните amount и currency с вашим заказом.
    // Отметьте заказ оплаченным атомарно.
}

http_response_code(200);
echo 'OK';
07

Выплата на AR-кошелёк

POST https://adsrekpay.com/api/pay/payout.php

Это не внешний вывод. Метод переводит средства только внутри Adsrek Pay на AR-кошелёк получателя. Комиссия 0.50% списывается с владельца магазина сверх суммы перевода.
Запрос
{
  "shop_id": 1001,
  "api_key": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "order_id": "PAYOUT-1001",
  "amount": "10.00",
  "currency": "RUB",
  "target": "AR584193027",
  "sign": "HMAC_SHA256_HEX"
}
Ответ
{
  "ok": true,
  "payout": {
    "transfer_id": 9021,
    "amount": "10.00",
    "currency": "RUB",
    "recipient": "AR584193027"
  }
}

order_id обязателен и обеспечивает идемпотентность. При повторе успешно выполненной выплаты API вернёт сохранённый результат, а не спишет деньги ещё раз.

08

Статусы счёта

Фактические статусы Merchant API v1.

newОжидает оплатыСчёт создан и доступен клиенту.
paidОплаченФинальный успешный статус.
expiredИстёкПрошло 24 часа без оплаты.
cancelОтменёнФинальный статус отмены.
refundedВозвращёнСредства возвращены.
09

Ошибки API

Ответ ошибки имеет вид {"ok":false,"error":"CODE"}.

HTTPКодЗначение
400INVALID_JSONТело запроса не удалось разобрать.
401AUTH_REQUIREDОтсутствуют shop_id, api_key или корректная 64-символьная подпись.
401SHOP_NOT_FOUNDСайт не найден, выключен или API KEY неверен.
401BAD_SIGNATUREHMAC-подпись не совпала.
401SHOP_SECRET_ERRORСервер не смог расшифровать SECRET KEY сайта.
404INVOICE_NOT_FOUNDСчёт с указанным order_id не найден.
405METHOD_NOT_ALLOWEDИспользован метод, отличный от POST.
413PAYLOAD_TOO_LARGEТело запроса превышает 65 536 байт.
422BAD_CURRENCYВалюта не поддерживается.
422BAD_AMOUNTСумма не прошла нормализацию.
422BAD_INVOICEПустой order_id или сумма меньше минимальной.
422BAD_CALLBACK_URLCallback URL не является публичным HTTPS-адресом.
422ORDER_ID_CONFLICTПовторный order_id передан с другой суммой или валютой.
422RECIPIENT_NOT_FOUNDПолучатель внутренней выплаты не найден.
422INSUFFICIENT_FUNDSНа балансе магазина недостаточно суммы и комиссии.
422DUPLICATE_OR_IN_PROGRESSВыплата с этим order_id уже выполняется или завершилась ошибкой.
422SELF_PAYOUT_NOT_ALLOWEDНельзя выполнить API-выплату самому себе.
10

Готовые примеры

Код для серверной интеграции.

PHP cURL: создать счёт
<?php
$shopId = 1001;
$apiKey = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
$secretKey = getenv('ADSREK_PAY_SECRET');
$orderId = 'ORDER-1001';
$amount = number_format(10, 2, '.', '');
$currency = 'RUB';

$canonical = implode('|', ['create', $shopId, $apiKey, $orderId, $amount, $currency]);
$payload = [
    'shop_id' => $shopId,
    'api_key' => $apiKey,
    'order_id' => $orderId,
    'amount' => $amount,
    'currency' => $currency,
    'description' => 'Оплата заказа ' . $orderId,
    'sign' => hash_hmac('sha256', $canonical, $secretKey),
];

$ch = curl_init('https://adsrekpay.com/api/pay/create.php');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 15,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($response === false) {
    throw new RuntimeException(curl_error($ch));
}
curl_close($ch);

$data = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
if ($httpCode !== 200 || empty($data['ok'])) {
    throw new RuntimeException($data['error'] ?? 'Adsrek Pay API error');
}
header('Location: ' . $data['payment_url']);
exit;
Python: создать счёт
import hashlib
import hmac
import os
import requests

shop_id = 1001api_key = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
secret_key = os.environ["ADSREK_PAY_SECRET"]
order_id = "ORDER-1001"
amount = "10.00"
currency = "RUB"

canonical = f"create|{shop_id}|{api_key}|{order_id}|{amount}|{currency}"
sign = hmac.new(secret_key.encode(), canonical.encode(), hashlib.sha256).hexdigest()

payload = {
    "shop_id": shop_id,
    "api_key": api_key,
    "order_id": order_id,
    "amount": amount,
    "currency": currency,
    "description": f"Оплата заказа {order_id}",
    "sign": sign,
}
response = requests.post("https://adsrekpay.com/api/pay/create.php", json=payload, timeout=15)
response.raise_for_status()
data = response.json()
print(data["payment_url"])
JavaScript: только перенаправление
// Счёт создаётся только на вашем сервере, где хранится SECRET KEY.
const response = await fetch('/your-server/create-adsrek-invoice', {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({order_id: 'ORDER-1001'})
});
const data = await response.json();
if (!data.payment_url) throw new Error('Не удалось создать счёт');
window.location.assign(data.payment_url);
11

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

Обязательные правила для боевой интеграции.

  • SECRET KEY — только на сервере. Не вставляйте его в HTML, JavaScript, мобильное приложение или публичный репозиторий.
  • Всегда используйте HTTPS. Callback на HTTP и локальные/private IP блокируются.
  • Проверяйте подпись через hash_equals. Обычное сравнение строк может быть уязвимо к timing-атакам.
  • Проверяйте сумму, валюту и order_id. Подписанный callback нужно сопоставить с данными заказа в вашей базе.
  • Обрабатывайте повторные уведомления идемпотентно. Один счёт не должен зачисляться дважды.
  • После перевыпуска ключей старые ключи сразу перестают работать. Обновляйте конфигурацию атомарно.
  • Храните резервную копию config/paycore.local.php. Этот файл нужен Adsrek Pay для расшифровки SECRET KEY магазинов.
12

Ограничения и текущая версия

Фактические параметры Merchant API v1.

Версия

Merchant API v1. Endpoint-адреса содержат PHP-файлы и должны использоваться без изменения.

Минимальная сумма

0.01 в выбранной валюте.

Комиссия приёма

1.00% удерживается из суммы, поступающей владельцу магазина.

Комиссия API-выплаты

0.50% списывается дополнительно с владельца магазина.

Sandbox

Отдельный тестовый контур пока не предусмотрен. Для проверки используйте отдельный сайт и минимальную сумму.

Лимит запросов

Специальный тарифный rate limit в текущей версии не задан. Не отправляйте частые циклические запросы: используйте callback и разумный polling.