Эндпоинты Колбеки Сайт Быстрый старт
Документация для мерчантов

SyncroPay API
приём и выплаты

REST-интеграция card-to-card в гривне. Все методы — POST с JSON, авторизация по токену, результат — подписанный колбек со status_id.

Base pay.syncropay.tech/api Валюта UAH Метод POST · JSON
Быстрый старт

Приём платежа за 4 шага

1 · Создать заказ

/api/v4/order/create с order_id и суммой.

2 · Показать реквизит

Из ответа — cred_formatted и redirect_url.

3 · Колбек

Ловите подписанный вебхук с status_id.

4 · Зачесть

status_id = 5 → выдайте заказ клиенту.

Расчёты. Клиент платит в UAH, баланс ведётся в USDT по согласованному курсу. Комиссия и merch_amount приходят в ответе и колбеке.
Доступы

Учётные данные и базовый URL

Выдаёт менеджер после подключения:

ПараметрНазначение
API-токенСекретный ключ для заголовка x-api-token. Аутентифицирует все запросы.
webhook_secretСекрет для проверки подписи X-Signature входящих колбеков (HMAC-SHA256).
callback_urlВаш эндпоинт для колбеков (настраивается в аккаунте).
base URL
https://pay.syncropay.tech/api
Храните секреты на бэкенде. Никогда не встраивайте x-api-token и webhook_secret в клиентский код или приложения. Только server-to-server.
Безопасность

Авторизация

Токен — в заголовке x-api-token (либо Authorization: Bearer <токен>). Без валидного токена — ошибка 101 (HTTP 401).

HTTP headers
x-api-token: sk_live_ваш_секретный_токен
Content-Type: application/json
Проверка связи: POST /api/v1/health_check{ "status": "ok" } (без авторизации).
Соглашения

Формат запросов и ответов

  • Все методы — POST, тело и ответ — JSON (UTF-8).
  • Успех: { "status": "ok", ... }. Ошибка: { "status": "error", "error_code": N, "error": "..." }.
  • Суммы — в гривнах (1500 / 1500.50).
  • order_id — ваш идентификатор заказа, уникальный. Повтор → ошибка 104. Это же и защита от дублей — переиспользуйте тот же order_id при сетевых ретраях.
  • cred_type — тип реквизита; поддерживается только карта = 1.
Приём · PayIn

Создать заказ (v4)

POST/api/v4/order/create Создаёт заказ и сразу возвращает карту для оплаты и ссылку. Поддерживает автоподбор суммы (randomize).

Параметры тела

ПолеТипОписание
order_id обязstringВаш ID заказа, уникальный.
amount обязnumberСумма в UAH.
cred_type опцnumberТип реквизита, только 1 (карта). По умолчанию 1.
customer_id опцstringID клиента на вашей стороне.
return_url опцstringКуда вернуть клиента после оплаты (иначе — наша страница оплаты).
randomize_enable опц0 | 1Включить автоподбор незанятой суммы, если базовая занята.
randomize_direction опцstringincrease (по умолч.) или decrease.
randomize_stepping опцnumberШаг подбора, UAH (по умолч. 5).
randomize_max_steps опцnumberМакс. число шагов (1–50, по умолч. 10).
randomize_max_final_amount опцnumberПотолок итоговой суммы при increase.

Запрос

curl -X POST https://pay.syncropay.tech/api/v4/order/create \
  -H "x-api-token: sk_live_ваш_токен" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": "ORDER-10245",
    "amount": 1500,
    "cred_type": 1,
    "return_url": "https://shop.example/success"
  }'
const res = await fetch("https://pay.syncropay.tech/api/v4/order/create", {
  method: "POST",
  headers: {
    "x-api-token": process.env.SYNCROPAY_TOKEN,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    order_id: "ORDER-10245", amount: 1500, cred_type: 1,
    return_url: "https://shop.example/success",
  }),
});
const data = await res.json();
// data.redirect_url → редирект клиента; data.cred_formatted → карта
import os, requests

res = requests.post(
    "https://pay.syncropay.tech/api/v4/order/create",
    headers={"x-api-token": os.environ["SYNCROPAY_TOKEN"]},
    json={
        "order_id": "ORDER-10245",
        "amount": 1500,
        "cred_type": 1,
    },
)
data = res.json()  # data["redirect_url"], data["cred_formatted"]

Ответ status: ok

application/json
{
  "status": "ok",
  "order_id": "ORDER-10245",
  "transaction_id": 100251,
  "amount": 1500,
  "amount_initial": 1500,
  "usdt_amount": 36.14,
  "usdt_rate": 41.5,
  "status_id": 2,
  "bank_name": "Mono",
  "receiver_name": "IVAN P.",
  "cred": "5375411234567890",
  "cred_formatted": "5375 41** **** 7890",
  "cred_type": 1,
  "redirect_url": "https://pay.syncropay.tech/checkout/pk_9f3c...e1",
  "deadline": "2026-07-09T12:20:00.000Z"
}
Показать клиенту реквизит (cred_formatted, bank_name, receiver_name) либо редиректить на redirect_url. При randomize_enable=1 итоговая amount может отличаться от запрошенной — списывать нужно ровно amount, исходная — в amount_initial.
Приём · PayIn

Создать заказ (v1)

POST/api/v1/order/create Упрощённый вариант без автоподбора суммы. Тело — order_id, amount, cred_type; ответ идентичен v4.

Используйте v4, если нужен автоподбор суммы (снижает пересечения реквизитов при высоком потоке); иначе достаточно v1.

Приём · PayIn

Статус заказа

POST/api/v1/order/status Тело: { "order_id": "..." } или { "transaction_id": ... }. Нет → ошибка 404.
application/json
{
  "status": "ok",
  "order_data": {
    "order_id": "ORDER-10245",
    "transaction_id": "100251",
    "amount": "1500.00",
    "amount_initial": "1500.00",
    "commission": "30.00",
    "merch_amount": "1470.00",
    "usdt_amount": "36.14",
    "usdt_rate": "41.5",
    "cred": "5375411234567890",
    "cred_formatted": "5375 41** **** 7890",
    "receiver_name": "IVAN P.",
    "receiver_bank": "Mono",
    "status_id": "5",
    "deadline": "2026-07-09T12:20:00.000Z"
  }
}
Приём · PayIn

Список заказов

POST/api/v1/order/list Тело (опц.): { "status_id": N } — фильтр по статусу. Возвращает { "status":"ok", "orders":[ ... ] }.
Выплаты · PayOut

Создать выплату

POST/api/v2/payout/create Выплата на карту получателя.

Параметры тела

ПолеТипОписание
order_id обязstringВаш ID выплаты, уникальный.
amount обязnumberСумма в UAH.
cred обязstringНомер карты получателя (проверка по алгоритму Луна).
cred_type опцnumberТолько 1 (карта).
recipient_name опцstringФИО получателя.
receiver_bank опцstringБанк получателя.
curl -X POST https://pay.syncropay.tech/api/v2/payout/create \
  -H "x-api-token: sk_live_ваш_токен" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": "PAYOUT-556",
    "amount": 3200,
    "cred": "5375411234567890",
    "cred_type": 1,
    "recipient_name": "Іван Петренко",
    "receiver_bank": "ПриватБанк"
  }'
const res = await fetch("https://pay.syncropay.tech/api/v2/payout/create", {
  method: "POST",
  headers: {
    "x-api-token": process.env.SYNCROPAY_TOKEN,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    order_id: "PAYOUT-556", amount: 3200,
    cred: "5375411234567890", cred_type: 1,
    recipient_name: "Іван Петренко",
  }),
});
status: ok
{
  "status": "ok",
  "payout_id": "100252",
  "payout_type": "CARD",
  "amount": "3200.00",
  "commission": "48.00",
  "final_amount": "3248.00",
  "cred_formatted": "5375 41** **** 7890",
  "currency": { "id": "1", "code": "UAH", "title": "UAH" },
  "receiver_country": "UA",
  "receiver_bank": "ПриватБанк"
}
Выплаты · PayOut

Статус и список выплат

POST/api/v2/payout/statusТело: { "order_id" } или { "payout_id" }. Нет → ошибка 110. Возвращает payout_status: NEW · PROCESSING · COMPLETED · FAILED · CANCELLED.
POST/api/v1/payouts/listТело (опц.): { "status": "COMPLETED" }. Возвращает { "payouts":[ ... ] }.
Споры

Апелляции

Если клиент оплатил, но заказ не подтверждён, мерчант открывает апелляцию с чеком — заявка уходит в спор (status_id = 7), оператор рассматривает.

POST/api/v1/appeal/createТело: { "order_id", "comments", ... }. Открывает спор по заказу.
POST/api/v1/appeal/statusСтатус апелляции по order_id.
POST/api/v1/appeal/listСписок апелляций мерчанта.
Колбеки

Жизненный цикл

Типовой путь приёма по status_id. На каждой смене статуса приходит колбек.

status_id 1
NEW
Заказ создан
status_id 2
CRED_ISSUED
Реквизит выдан, ждём оплату
status_id 3
CUSTOMER_PAID
Клиент оплатил / сверка
status_id 5
COMPLETED ✓
Средства зачтены
Зачисляйте заказ только при status_id = 5 (COMPLETED). Остальные статусы промежуточные и не гарантируют поступление средств.
Колбеки

Формат колбека

На каждой смене статуса мы шлём POST на ваш callback_url с JSON-телом и заголовком X-Signature. Отвечайте HTTP 2xx, иначе будут ретраи.

Тело — приём (PayIn)

POST → ваш callback_url · X-Signature: <hex>
{
  "order_id": "ORDER-10245",
  "transaction_id": 100251,
  "amount": "1500.00",
  "amount_initial": "1500.00",
  "commission": "30.00",
  "merch_amount": "1470.00",
  "status_id": 5,
  "cred": "5375411234567890",
  "cred_type": "1",
  "receiver_name": "IVAN P.",
  "receiver_bank": "Mono"
}

Тело — выплата (PayOut)

POST → ваш callback_url
{
  "status": "ok",
  "payout_id": "100252",
  "order_id": "PAYOUT-556",
  "type": "CARD",
  "amount": "3200.00",
  "commission": "48.00",
  "final_amount": "3248.00",
  "payout_status": "COMPLETED",
  "cred_formatted": "5375 41** **** 7890",
  "currency": { "id": "1", "code": "UAH", "title": "UAH" },
  "country_iso": "UA"
}

Доставка и ретраи

  • До 5 попыток с интервалами 0, 1, 5, 15, 60 минут, пока не получим 2xx.
  • Обработчик должен быть идемпотентным: дедуп по (order_id, status_id) — один и тот же статус может прийти повторно.
  • Всегда проверяйте X-Signature перед обработкой.
Колбеки

Проверка подписи

Заголовок X-Signature — это HMAC-SHA256(webhook_secret, тело_запроса) в hex. Считайте HMAC от сырого тела (до JSON-парсинга) и сравните в константном времени.

import crypto from "node:crypto";

// нужно СЫРОЕ тело — express.raw({ type: "application/json" })
app.post("/callback", express.raw({ type: "*/*" }), (req, res) => {
  const got = req.headers["x-signature"];
  const exp = crypto.createHmac("sha256", process.env.SYNCROPAY_SECRET)
                     .update(req.body).digest("hex");
  const a = Buffer.from(got || ""), b = Buffer.from(exp);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b))
    return res.sendStatus(401);

  const cb = JSON.parse(req.body);
  if (cb.status_id === 5) markOrderPaid(cb.order_id);
  res.sendStatus(200);
});
// $raw — сырое тело: file_get_contents("php://input")
$raw = file_get_contents("php://input");
$got = $_SERVER["HTTP_X_SIGNATURE"] ?? "";
$exp = hash_hmac("sha256", $raw, getenv("SYNCROPAY_SECRET"));

if (!hash_equals($exp, $got)) { http_response_code(401); exit; }

$cb = json_decode($raw, true);
if ((int)$cb["status_id"] === 5) markOrderPaid($cb["order_id"]);
http_response_code(200);
Считайте HMAC от сырого тела, а не от повторно сериализованного JSON — порядок ключей и пробелы должны совпадать байт-в-байт с полученным телом.
Справочник

Коды статусов (status_id)

status_idКодЗначение
1NEWЗаказ создан.
2CRED_ISSUEDРеквизит выдан, ждём оплату клиента.
3CUSTOMER_PAIDКлиент отметил оплату / идёт сверка.
5COMPLETEDУспех. Средства зачтены. Терминальный.
4CANCELLEDОтменён. Терминальный.
6REJECTEDОтклонён. Терминальный.
7APPEALОткрыт спор / апелляция.
8NOT_TAKENНе взят в работу (нет реквизита).
9EXPIREDИстёк срок оплаты. Терминальный.

Выплаты используют payout_status: NEW · PROCESSING · COMPLETED · FAILED · CANCELLED.

Справочник

Коды ошибок

Ошибки: { "status": "error", "error_code": N, "error": "текст" }.

error_codeHTTPПричина
101401Мерчант не найден или неактивен (плохой токен).
102400Сумма меньше минимально допустимой.
103422Сумма больше максимально допустимой.
104409Заказ с таким order_id уже существует.
105400Неверный cred_type (поддерживается только карта = 1).
106400Нет подходящего реквизита (карты) под заказ.
108400Неверный номер карты / формат реквизита.
109400Выплата: недостаточно баланса или нет трейдера.
110404Выплата не найдена.
404404Заказ не найден.
Финал

Чеклист интеграции

  1. Получить у менеджера API-токен, webhook_secret, задать callback_url, согласовать лимиты и курс.
  2. Проверить связь: POST /api/v1/health_check.
  3. Реализовать /api/v4/order/create с уникальным order_id.
  4. Показать клиенту реквизит (cred_formatted) или редирект на redirect_url.
  5. Поднять эндпоинт колбеков: проверка X-Signature → зачисление при status_id = 5 → ответ 2xx.
  6. Сделать обработчик идемпотентным (дедуп по order_id + status_id).
  7. Fallback: периодически опрашивать /api/v1/order/status.
  8. Протестировать на тестовых доступах, затем переключиться на боевые.
Нужна помощь? Пришлите ваш callback_url менеджеру — поможем с тестовым прогоном полного цикла до status_id = 5.
SyncroPay API · UAH card-to-card.
Комиссии, курсы и лимиты фиксируются в договоре подключения.
На сайт · Наверх ↑