EmiPay API для платформ
Partner API · v1

API для платформ-виконавців

Платформа бере виплати (Pay-out) зі стакану EmiPay, переказує кошти одержувачу і надсилає квитанцію. За кожну виконану виплату платформа отримує USDT на свій баланс в EmiPay.

Кабінет платформи залишається: оператори бачать заявки, статистику, баланс і спори та можуть узяти виплату вручну.

1Стакан

Ви отримуєте доступні виплати: список і вебхуки про появу та зникнення.

2Взяти

Перший, хто взяв виплату, отримує її разом з карткою одержувача.

3Виплатити

Ви переказуєте гривню на картку одержувача.

4Квитанція

Надсилаєте квитанцію — виплата завершується, USDT зараховано.

Доступ і ключ

Базова адресаhttps://partner.emipay.net/api/partner/v1Усі методи
API-ключКабінет → «Інтеграція API» → ключ з правами read і executeЗаголовок Authorization: Bearer emi_…. Показується один раз.
Секрет вебхукаКабінет → «Інтеграція API» → вебхук з вашою адресоюПеревірка підпису подій (whsec_…). Показується один раз.

Ключі й вебхуки створює супервайзер платформи. Ключ можна обмежити IP-адресами ваших серверів. До 10 активних ключів на акаунт.

API — лише для запитів сервер-сервер. Не вставляйте ключ у код сторінки чи мобільного застосунку.

Формат запитів

  • Тіло запитів і відповідей — JSON (Content-Type: application/json).
  • Кожен POST — із заголовком Idempotency-Key (унікальний рядок): повтор з тим самим ключем не виконає дію вдруге, тому запит можна безпечно повторити після мережевої помилки.
  • Суми — рядки: гривня з 2 знаками ("1800.00"), USDT з 6 ("38.730671"). Час — мілісекунди Unix.
  • Ліміт — 600 запитів на хвилину на акаунт. Залишок — у заголовку X-RateLimit-Remaining, перевищення — 429.
  • Помилка — HTTP 4xx і {"error":"…","request_id":"…"}. Вказуйте request_id, звертаючись у підтримку.
Робота з виплатами

Увімкнути прийом

POST/api/partner/v1/intake

Поки прийом вимкнено, стакан порожній і взяти виплату не можна. GET /profile показує допуск (напрями й межі сум), стан прийому та баланс.

Запит
curl -X POST https://partner.emipay.net/api/partner/v1/intake \
  -H "Authorization: Bearer $EMIPAY_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"enabled": true}'

Стакан

GET/api/partner/v1/orders/available?page=1

Початковий стан стакану — список доступних виплат, по 50 на сторінку. Даних одержувача в стакані немає: вони з’являються після взяття.

Запит
curl https://partner.emipay.net/api/partner/v1/orders/available?page=1 \
  -H "Authorization: Bearer $EMIPAY_KEY"
Відповідь 200
{
  "page": 1,
  "total": 1,
  "intake": true,
  "rows": [
    {
      "id": "100edd64-1f20-42db-85a8-e52fc4896646",
      "num": 102121,
      "direction": "payout",
      "status": "pending",
      "currency": "UAH",
      "settlement_currency": "USDT",
      "amount": "1800.00",
      "settlement_amount": "38.730671",
      "reward": "0.000000",
      "rate": "46.48",
      "expires": 1793228865353,
      "created": 1793217888298,
      "updated": 1793217888298
    }
  ]
}
amountСкільки гривень виплатити одержувачу
settlement_amountСкільки USDT отримає платформа за цю виплату
rateВаш курс: amount ÷ settlement_amount
expiresДо коли виплата доступна / має бути виконана

Далі тримайте стакан актуальним за вебхуками trade.available і trade.unavailable (див. «Вебхуки»). Раз на 1–2 хвилини звіряйте його з цим списком — на випадок втраченої доставки.

Взяти виплату

POST/api/partner/v1/orders/{id}/accept

Перший, хто взяв виплату (трейдер або платформа), отримує її. У відповіді — заявка зі статусом active і карткою одержувача recipient.

Запит
curl -X POST https://partner.emipay.net/api/partner/v1/orders/100edd64-1f20-42db-85a8-e52fc4896646/accept \
  -H "Authorization: Bearer $EMIPAY_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{}'
Відповідь 200
{
  "id": "100edd64-1f20-42db-85a8-e52fc4896646",
  "num": 102121,
  "direction": "payout",
  "status": "active",
  "amount": "1800.00",
  "settlement_amount": "38.730671",
  "rate": "46.48",
  "recipient": "5375414112345672",
  "expires": 1793228865353,
  …
}
  • 200 — виплата ваша: переказуйте на recipient до expires.
  • 409 — її вже взяли — приберіть зі стакану.
  • {"ok":true,"result":"auction","auction_until":…} — на виплату кілька претендентів одночасно; до auction_until визначиться виконавець — прийде trade.accepted (ваша) або trade.unavailable (не ваша).

Квитанція

POST/api/partner/v1/orders/{id}/receipt

Після переказу надішліть квитанцію — PDF або фото, до 10 МБ, у base64. Заявка переходить у paid, ми підтверджуємо виплату в джерелі, і вона стає completed — USDT зараховано на баланс платформи. Усі квитанції перевіряє ШІ: переконайтеся, що реквізит одержувача (карта / IBAN) і сума збігаються із заявкою і їх добре видно.

Запит
curl -X POST https://partner.emipay.net/api/partner/v1/orders/100edd64-1f20-42db-85a8-e52fc4896646/receipt \
  -H "Authorization: Bearer $EMIPAY_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"filename": "receipt.pdf", "base64": "JVBERi0xLjQK…"}'

Кілька файлів до однієї виплати: усі, крім останнього, надсилайте з "more": true — виплата закривається після останнього файлу.

Запит
POST /orders/{id}/receipt   {"filename": "1.jpg", "base64": "…", "more": true}
POST /orders/{id}/receipt   {"filename": "2.jpg", "base64": "…"}

Відмова

POST/api/partner/v1/orders/{id}/decline

Не можете виконати взяту виплату — відмовтеся з причиною:

Запит
curl -X POST https://partner.emipay.net/api/partner/v1/orders/100edd64-1f20-42db-85a8-e52fc4896646/decline \
  -H "Authorization: Bearer $EMIPAY_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"reason": "error", "comment": "…"}'
  • error — помилково взяли: виплата повертається в стакан для інших виконавців.
  • wrong_requisite — реквізит одержувача неправильний (картка заблокована, не існує): виплату буде скасовано.

Ваші заявки й баланс

GET/api/partner/v1/orders?status=active&page=1
GET/api/partner/v1/orders/{id}
GET/api/partner/v1/balance
GET/api/partner/v1/profile
GET/api/partner/v1/events?after=0
GET/api/partner/v1/ping

Ваші заявки за статусом (active, paid, review, disputed, completed, cancelled, expired), одна заявка, баланс і журнал подій — запасний варіант до вебхуків.

Вебхуки

Події

EmiPay надсилає події на вашу адресу. Відповідайте 2xx протягом 10 с, інакше доставку буде повторено (10 с, 30 с, 2 хв, 10 хв, 30 хв, 1 год, 3 год, 6 год). Доставка «щонайменше один раз»: пропускайте повтори за EmiPay-Event-Id.

HTTP
POST https://your-server/emipay
Content-Type: application/json
EmiPay-Event: trade.available
EmiPay-Event-Id: evt_3f2a…
EmiPay-Delivery: 7c1e…
EmiPay-Signature: t=1793218065,v1=<hex HMAC-SHA256(secret, t + "." + body)>

{"id":"evt_3f2a…","type":"trade.available","created":1793218065475,"data":{ …order… }}
ПодіяКолиЩо зробити
trade.availableВиплата з’явилася в стакані (нова або повернута в пул) у межах вашого допускуДодати в стакан; data — заявка, як у списку
trade.unavailableВиплата зникла зі стакану: reason = taken (узяв інший виконавець), cancelled, expiredПрибрати зі стакану
trade.acceptedВиплату закріплено за вами (зокрема після аукціону)Виплатити до expires
trade.deadlineЧас на виплату спливаєНадіслати квитанцію або відмовитись
trade.paidКвитанцію прийнято, ідемо на підтвердження—
trade.completedВиплату завершено, USDT зараховано—
trade.review, trade.disputedВиплату передано на перевірку / відкрито спірЗв’язатися з підтримкою, дослати докази в кабінеті
trade.cancelled, trade.expired, trade.recalculatedЗаявку скасовано / прострочено / перерахованоОновити у себе
trade.unavailable
{"id":"evt_…","type":"trade.unavailable","created":1793218065475,"data":{"id":"100edd64-…","num":102121,"reason":"taken"}}

Перевірка підпису

Підпис — HMAC-SHA256 від t + "." + тіло секретом вебхука. Рахуйте його на сирому тілі запиту й відкидайте t, старший за 5 хвилин.

import { createHmac, timingSafeEqual } from 'node:crypto';

// rawBody — the request body exactly as received (string), header — EmiPay-Signature
function verify(rawBody, header, secret) {
  const { t, v1 } = Object.fromEntries(header.split(',').map(p => p.split('=')));
  if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
  const expected = createHmac('sha256', secret).update(t + '.' + rawBody).digest('hex');
  return v1?.length === expected.length && timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}
Довідники

Статуси заявки

СтатусЗначення
pendingУ стакані, ще ніхто не взяв
activeВзята вами — виплатіть і надішліть квитанцію
paidКвитанцію отримано, підтверджуємо в джерелі
reviewНа перевірці адміністрацією
disputedВідкрито спір
completedВиплату завершено, USDT зараховано
cancelledСкасовано
expiredЧас вийшов

Коди помилок

КодКоли
401Немає ключа, ключ неправильний, прострочений або відкликаний
403Ключ без потрібного права, запит з недозволеного IP або прийом вимкнено адміністрацією
404Заявку не знайдено (або вона не ваша)
409Стан заявки не дозволяє дію — наприклад, її вже взяли
413Файл квитанції завеликий
422Неправильні дані запиту
429Перевищено ліміт запитів

Чекліст запуску

  • Ключ з правами read і execute збережено в секретах сервера; задано IP ваших серверів.
  • Вебхук доступний з інтернету по HTTPS і відповідає 2xx за 10 секунд.
  • Обробник перевіряє EmiPay-Signature на сирому тілі й пропускає повтори за EmiPay-Event-Id.
  • Стакан будується зі списку й оновлюється за trade.available / trade.unavailable; раз на 1–2 хвилини — звірка зі списком.
  • Кожен POST має унікальний Idempotency-Key.
  • Оброблено 409 на взятті (виплату взяв інший) і відповідь auction.
  • Квитанція надсилається лише після фактичного переказу; кілька файлів — з "more": true.
  • Перша виплата — на невелику суму.
EmiPay Partner API · v1Нагору ↑