Introduction
Інтеграція прийому поповнень і створення виплат через P2P-обмін.
P2P Market API
P2P Market автоматично поєднує користувачів, які заводять кошти, з користувачами, які хочуть їх вивести: платник переказує кошти безпосередньо на реквізити активної виплати, а платформа зіставляє операції та оновлює їхні статуси.
Базовий сценарій
- Мерчант створює виплату через
POST /api/v1/payout. - Для користувача створюється тимчасовий URL через
POST /api/v1/auth/token. - Користувач створює платіж і переказує кошти на надані реквізити.
- Платформа перевіряє оплату, зараховує її до виплати та надсилає webhook.
- Мерчант обробляє webhook і за потреби звіряє стан через status endpoint.
Усі запити до API v1 передають API-ключ мерчанта в заголовку:
X-API-Key: your-api-key
Accept: application/json
Content-Type: application/json
API-ключ, URL для webhook і список дозволених IP налаштовуються в кабінеті мерчанта. Ключ не можна передавати у frontend-коді, URL або логах.
Банки та ліміти
Платформа підтримує всі актуальні банки, доступні для відповідної валюти й країни. Каталог динамічний, тому не зберігайте перелік банків у коді:
- глобальний каталог валюти:
GET /api/currencies/{code}/banks; - банки, дозволені мерчанту:
GET /api/v1/merchant/settings; - доступність для конкретного користувача:
GET /api/v1/order-limits.
Фактичний список може бути вужчим через валюту, налаштування мерчанта, користувацькі обмеження або тимчасову недоступність реквізитів.
Тарифи
Розрахункова валюта комісій — USD.
- Успішне поповнення коштує 0,03 USD.
- Для виплати фактично сплачена сума спочатку конвертується в USD за курсом платформи на момент списання, після чого застосовується відсоток тарифу мерчанта.
- Результат округлюється до двох знаків і списується з USD-балансу мерчанта.
- Поточні значення тарифів повертає
GET /api/v1/merchant/settings.
Формула комісії за виплату:
fee_usd = round(convert_to_usd(paid_amount, platform_rate) × tariff_percent / 100, 2)
Наприклад, 4 100 UAH за курсу платформи 41 UAH/USD — це 100 USD. За тарифу 1% комісія становить 1,00 USD. Відсоткова комісія списується, коли виплату завершено або її фактична сума досягла повної суми. За частково зібраною виплатою до цього моменту відсоткова комісія не списується. Якщо виплату скасовано після списання, система створює повернення комісії для зафіксованої сплаченої суми.
Окремий endpoint верифікації квитанцій має власний тариф, який указано в його описі.
Статуси
Платежі використовують статуси new, pending, paid, confirmed,
disputed, refunded, cancelled та expired.
Виплати використовують статуси pending, processing, partially_paid,
completed, cancelled, requires_verification та paused_by_user.
Не визначайте фінальний результат лише за HTTP-відповіддю створення. Обробляйте webhook і періодично звіряйте фінальний статус через API.
Технічний контракт
- Версія API:
v1; версія поточної специфікації:1.0.0. - Грошові значення передаються як JSON number. Комісії в USD округлюються до двох знаків.
- Дати у webhook і більшості API-відповідей серіалізуються в ISO 8601.
Поля ресурсу виплати
created_at/updated_atмають форматYYYY-MM-DD HH:mm:ss. Серверна часова зона —Europe/Kyiv. merchant_payout_idє ключем ідемпотентності створення виплати. Не використовуйте його повторно для іншої операції.merchant_payment_idідентифікує платіж у системі мерчанта, якщо його передано.- Ліміт API — 9 200 запитів за 60 секунд на мерчанта. При
429використовуйтеRetry-Afterабоretry_after. - Таймаут вихідного webhook-запиту — 30 секунд.
- Завантаження endpoint-а верифікації квитанцій зберігаються 90 днів за замовчуванням; строк може бути змінений конфігурацією середовища.
Номери карток, квитанції та API-ключі є чутливими даними. Не записуйте їх у відкриті логи, обмежуйте доступ за принципом найменших привілеїв і зберігайте лише стільки, скільки потрібно для операції та законних вимог.
Зміни й сумісність
Актуальний стабільний контракт розміщено в OpenAPI-файлі цієї документації. Несумісні зміни мають виходити в новій версії API; deprecated endpoint-и позначаються в документації до видалення.
Зміни від 24.07.2026:
- уточнено тариф 0,03 USD і конвертацію комісії виплати;
- каталог банків зроблено динамічним;
- уніфіковано помилки та
Retry-After; - виправлено контракти платежів, виплат і webhook;
- увімкнено генерацію OpenAPI та Postman.
Sandbox
Sandbox-режим визначається налаштуванням мерчанта, а не полем запиту. Відповіді
містять sandbox_mode, а також заголовок X-Sandbox-Mode: true. Тестові дані
ізольовані від production; перед запуском потрібно окремо перевірити всі
успішні, помилкові та повторні webhook-сценарії.
Помилки API
Помилки мають єдину базову структуру:
{
"success": false,
"message": "Опис помилки",
"error_code": "VALIDATION_ERROR",
"errors": {
"field": ["Опис помилки поля"]
}
}
errors повертається лише тоді, коли є деталізація за полями. У sandbox
відповідь також може містити sandbox_mode і sandbox_notice.
HTTP-статуси
| HTTP | Що означає | Рекомендована дія |
|---|---|---|
| 400 | Операцію неможливо виконати в поточному стані | Виправити стан або ідентифікатор; не повторювати без змін |
| 401 | API-ключ відсутній або не пройшов перевірку | Перевірити ключ, активність та IP whitelist |
| 402 | Недостатньо USD на балансі | Поповнити баланс |
| 403 | Немає доступу до операції чи ресурсу | Перевірити власника, режим і права |
| 404 | Ресурс не знайдено | Перевірити ID |
| 422 | Дані не пройшли валідацію | Виправити поля з errors |
| 429 | Перевищено частоту запитів | Чекати кількість секунд із Retry-After |
| 500 | Внутрішня помилка | Повторити з backoff; передати підтримці request ID із власного логу |
| 502/503 | Залежний сервіс або ресурс тимчасово недоступний | Повторити з backoff |
Коди
error_code |
Значення |
|---|---|
API_KEY_MISSING |
Немає заголовка X-API-Key |
AUTHENTICATION_FAILED |
Ключ, активність мерчанта або IP whitelist не пройшли перевірку |
MERCHANT_ACCESS_DENIED |
Поточний стан мерчанта забороняє API |
RATE_LIMIT_EXCEEDED |
Вичерпано ліміт; дивіться retry_after і Retry-After |
VALIDATION_ERROR |
Помилки вхідних полів |
AUTHORIZATION_ERROR |
Form Request відхилив виконання операції |
DUPLICATE_PAYOUT_ID |
merchant_payout_id уже використано |
PAYOUT_NOT_FOUND |
Виплату не знайдено |
PAYOUT_NOT_CHANGEABLE |
Реквізити виплати вже не можна змінити |
PAYOUT_NOT_RESTORABLE |
Виплату не можна відновити |
SAME_CARD_NUMBER |
Передано поточний номер картки |
INVALID_ACTION |
Неприпустима зміна статусу |
ORDER_NOT_FOUND |
Платіж не знайдено |
ACCESS_DENIED |
Ресурс належить іншому мерчанту |
MODE_MISMATCH |
Sandbox/production режим не відповідає ресурсу |
CURRENCY_NOT_SUPPORTED |
Для валюти немає активних налаштувань |
INSUFFICIENT_BALANCE |
Недостатньо USD для платної операції |
BALANCE_ACCOUNT_NOT_FOUND |
Для мерчанта немає балансового акаунта |
VERIFICATION_UNAVAILABLE |
Сервіс верифікації тимчасово недоступний |
WEBHOOK_URL_NOT_CONFIGURED |
URL потрібного типу webhook не налаштовано |
WEBHOOK_DELIVERY_FAILED |
Тестовий webhook не доставлено |
INTERNAL_ERROR |
Неочікувана помилка платформи |
RESOURCE_NOT_FOUND |
Запитаний ресурс моделі не знайдено |
HTTP_ERROR |
Операцію перервано HTTP-винятком |
Повторні запити
Автоматично повторюйте лише мережеві помилки, 429, 500, 502 і 503,
використовуючи exponential backoff та jitter. Для створення виплати зберігайте
стабільний унікальний merchant_payout_id: після невизначеного результату
спочатку перевірте статус, щоб не створити дубль.
Приклад інтеграції
Замініть {API_BASE_URL} на адресу середовища, видану під час підключення.
Створення виплати
Для карткової виплати обов'язково передайте і номер картки, і ім'я власника.
merchant_payout_id має бути унікальним та стабільним для цієї операції.
curl --request POST '{API_BASE_URL}/api/v1/payout' \
--header 'X-API-Key: your-api-key' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"partner_user_id": "user-123",
"merchant_payout_id": "payout-20260724-001",
"amount_total": 1000,
"currency": "UAH",
"recipient_card_number": "4111111111111111",
"recipient_card_holder_name": "IVAN PETRENKO"
}'
Токен для користувача
curl --request POST '{API_BASE_URL}/api/v1/auth/token' \
--header 'X-API-Key: your-api-key' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"partner_user_id": "user-123",
"expires_in_minutes": 60,
"metadata": {
"name": "Ivan Petrenko",
"partner_registered_at": "2025-10-12T09:30:00Z"
}
}'
Перенаправте користувача на data.auth_url. Токен діє до data.expires_at;
після першого використання його можна повторно використати не довше 30 хвилин
і в будь-якому разі не довше загального строку дії.
Обробник webhook на PHP
Подія не має обгортки event/data: JSON містить ресурс безпосередньо, а назва
події передається в X-Event-Type. Секрет підпису — API-ключ мерчанта.
<?php
$rawBody = file_get_contents('php://input');
$receivedSignature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
$eventType = $_SERVER['HTTP_X_EVENT_TYPE'] ?? '';
$expectedSignature = hash_hmac('sha256', $rawBody, getenv('P2P_API_KEY'));
if (! hash_equals($expectedSignature, $receivedSignature)) {
http_response_code(401);
exit;
}
$payload = json_decode($rawBody, true, flags: JSON_THROW_ON_ERROR);
$resourceId = $payload['id'];
// Унікальний ключ обробки: $eventType + $resourceId.
// Спочатку надійно збережіть подію, потім виконайте бізнес-логіку.
processWebhookIdempotently($eventType, $resourceId, $payload);
http_response_code(204);
Важливо перевіряти HMAC до декодування JSON і підписувати саме незмінені байти тіла. Платформа вважає доставку успішною для будь-якого статусу 2xx. Невдалі доставки повторюються кожні 15 хвилин, загалом не більше п'яти спроб.
Node.js
Для Express зареєструйте raw parser на webhook-маршруті до звичайного JSON parser:
import crypto from 'node:crypto';
import express from 'express';
const app = express();
app.post('/p2p-webhook', express.raw({type: 'application/json'}), (req, res) => {
const received = req.get('X-Signature') ?? '';
const expected = crypto
.createHmac('sha256', process.env.P2P_API_KEY)
.update(req.body)
.digest('hex');
if (received.length !== expected.length ||
!crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected))) {
return res.sendStatus(401);
}
const eventType = req.get('X-Event-Type');
const payload = JSON.parse(req.body.toString('utf8'));
processWebhookIdempotently(eventType, payload.id, payload);
return res.sendStatus(204);
});
Python
import hashlib
import hmac
import json
import os
def handle_webhook(request):
raw_body = request.get_data()
received = request.headers.get("X-Signature", "")
expected = hmac.new(
os.environ["P2P_API_KEY"].encode(),
raw_body,
hashlib.sha256,
).hexdigest()
if not hmac.compare_digest(received, expected):
return "", 401
event_type = request.headers["X-Event-Type"]
payload = json.loads(raw_body)
process_webhook_idempotently(event_type, payload["id"], payload)
return "", 204
Звірка статусу
Webhook може бути повторним або запізнитися. Після невизначеного результату звіряйте стан:
curl --get '{API_BASE_URL}/api/v1/payout/status' \
--header 'X-API-Key: your-api-key' \
--header 'Accept: application/json' \
--data-urlencode 'merchant_payout_id=payout-20260724-001'
Для платежу використовуйте
GET /api/v1/order/status?payment_id={platform_payment_id}.
Authenticating requests
To authenticate requests, include a X-API-Key header with the value "your-api-key-here".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
API-ключ мерчанта. Передавайте його в заголовку X-API-Key. Ключ можна отримати в кабінеті мерчанта в блоці «API та безпека».
Аутентифікація
Створення токену авторизації
requires authentication
Створює тимчасовий токен для авторизації користувача в веб-інтерфейсі P2P системи.
Принцип роботи
- Створення токену - генерується унікальний токен з терміном дії
- Створення/оновлення користувача - система знаходить існуючого користувача або створює нового
- Збереження дати реєстрації - якщо передано
partner_registered_at, дата зберігається у профілі користувача - Перенаправлення - користувач переходить по
auth_urlдля авторизації - Автоматичний вхід - система автоматично авторизує користувача
- Доступ до інтерфейсу - користувач отримує доступ до веб-інтерфейсу
Сценарії використання
- Платежі - перенаправлення користувача на сторінку оплати
- Виплати - доступ до особистого кабінету для перегляду виплат
- Історія операцій - перегляд транзакцій та статусів
- Підтримка - доступ до чату з підтримкою
Безпека
- Токени мають обмежений час життя (за замовчуванням 60 хвилин)
- Після першого використання токен можна повторно використати протягом 30 хвилин, але не довше його загального строку дії
- Прострочені токени періодично видаляються системою
📅 Дата реєстрації користувача
Параметр partner_registered_at дозволяє передати дату реєстрації користувача в системі партнера.
Ця дата використовується для:
- Визначення статусу користувача - нові користувачі мають обмежений доступ до деяких функцій
- Фільтрації банків - новим користувачам можуть бути приховані певні банки (наприклад, PrivatBank)
- Аналітики та звітності - для розуміння поведінки користувачів залежно від їх "віку"
Якщо параметр не передано, використовується дата створення запису в нашій системі (created_at).
🔄 Переспрямування після авторизації
Після автоматичної авторизації користувач може бути перенаправлений на конкретні сторінки системи додавши параметр page до auth_url.
*Доступні сторінки для переспрямування:**
| Параметр | Призначення | Приклад URL |
|---|---|---|
deposit |
Сторінка створення поповнення | /auth?token=...&page=deposit |
payout |
Список виплат користувача | /auth?token=...&page=payout |
terms |
Умови користування | /auth?token=...&page=terms |
order |
Конкретне замовлення | /auth?token=...&page=order&orderId=123 |
Example request:
curl --request POST \
"https://api.p2p-market.net/api/v1/auth/token" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"partner_user_id\": \"user_12345\",
\"redirect_url\": \"https:\\/\\/yoursite.com\\/dashboard\",
\"metadata\": {
\"name\": \"Іван Петров\",
\"email\": \"[email protected]\",
\"telegram_id\": 123456789,
\"partner_registered_at\": \"2025-01-15 10:30:00\"
},
\"expires_in_minutes\": 120,
\"partner_registered_at\": \"2024-01-15 10:30:00\"
}"
const url = new URL(
"https://api.p2p-market.net/api/v1/auth/token"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"partner_user_id": "user_12345",
"redirect_url": "https:\/\/yoursite.com\/dashboard",
"metadata": {
"name": "Іван Петров",
"email": "[email protected]",
"telegram_id": 123456789,
"partner_registered_at": "2025-01-15 10:30:00"
},
"expires_in_minutes": 120,
"partner_registered_at": "2024-01-15 10:30:00"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/auth/token';
$response = $client->post(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'partner_user_id' => 'user_12345',
'redirect_url' => 'https://yoursite.com/dashboard',
'metadata' => [
'name' => 'Іван Петров',
'email' => '[email protected]',
'telegram_id' => 123456789,
'partner_registered_at' => '2025-01-15 10:30:00',
],
'expires_in_minutes' => 120,
'partner_registered_at' => '2024-01-15 10:30:00',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200, Успішне створення токену):
{
"success": true,
"data": {
"token": "m4WQ8kP6pS2vN7xR5cT9yH3jL1aB6dF8gK2zX4uV7nM9qE5w",
"expires_at": "2024-01-15T12:30:00Z",
"auth_url": "https://exchange.p2p-market.com/auth?token=m4WQ8kP6pS2vN7xR5cT9yH3jL1aB6dF8gK2zX4uV7nM9qE5w"
}
}
Example response (401, Невірний API ключ):
{
"success": false,
"message": "Невірний API ключ, аккаунт неактивний або IP адреса не дозволена",
"error_code": "AUTHENTICATION_FAILED"
}
Example response (422, Помилки валідації):
{
"success": false,
"message": "Помилки валідації",
"errors": {
"partner_user_id": [
"ID користувача у системі мерчанта є обов'язковим"
],
"expires_in_minutes": [
"Час життя токену має бути числом"
]
}
}
Example response (500, Внутрішня помилка сервера):
{
"success": false,
"message": "Помилка при створенні токена авторизації. Зверніться до підтримки.",
"error_code": "INTERNAL_ERROR"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішного виконання.
data
object
token
string
Тимчасовий 64-символьний токен авторизації.
expires_at
string
Дата завершення дії токена у форматі ISO 8601 (UTC).
auth_url
string
URL, на який потрібно перенаправити користувача.
Виплати
Отримання статусу виплати
requires authentication
Повертає поточний статус виплати за її merchant_payout_id.
Можливі статуси виплати
pending- Виплата створена, очікує обробкиprocessing- Виплата в процесі обробкиpartially_paid- Виплата частково сплаченаcompleted- Виплата повністю сплаченаcancelled- Виплата скасованаrequires_verification- Потребує ручної перевіркиpaused_by_user- Призупинена користувачем
Додаткова інформація
Відповідь містить детальну інформацію про:
- Суму виплати та отриману суму
- Дані про отримувача (номер карти, банк)
- Список платежів за цією виплатою
- Sandbox статус (якщо застосовно)
Example request:
curl --request GET \
--get "https://api.p2p-market.net/api/v1/payout/status?merchant_payout_id=payout_67890" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.p2p-market.net/api/v1/payout/status"
);
const params = {
"merchant_payout_id": "payout_67890",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/payout/status';
$response = $client->get(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'merchant_payout_id' => 'payout_67890',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200, Успішне отримання статусу):
{
"success": true,
"data": {
"id": 123,
"merchant_payout_id": "payout_67890",
"amount_total": 1000.5,
"amount_received": 750.3,
"currency": "UAH",
"status": "partially_paid",
"recipient_card_number": "1234567890123456",
"recipient_card_holder_name": "Ivan Petrov",
"recipient_bank_name": "PrivatBank",
"min_payment_amount": 100,
"max_payment_amount": 5000,
"is_sandbox": false,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T12:15:00Z",
"orders": [
{
"id": 456,
"amount": 500.3,
"status": "confirmed",
"created_at": "2024-01-15T11:00:00Z"
},
{
"id": 457,
"amount": 250,
"status": "confirmed",
"created_at": "2024-01-15T12:00:00Z"
}
]
},
"sandbox_mode": false
}
Example response (200, Статус sandbox виплати):
{
"success": true,
"data": {
"id": 124,
"merchant_payout_id": "test_payout_123",
"amount_total": 500,
"amount_received": 500,
"currency": "UAH",
"status": "completed",
"recipient_card_number": "1234567890123456",
"recipient_card_holder_name": "Test User",
"recipient_bank_name": "Test Bank",
"min_payment_amount": null,
"max_payment_amount": null,
"is_sandbox": true,
"created_at": "2024-01-15T10:31:00Z",
"updated_at": "2024-01-15T10:32:00Z",
"orders": []
},
"sandbox_mode": true,
"sandbox_notice": "Тестова виплата - не впливає на реальний баланс"
}
Example response (401, Невірний API ключ):
{
"success": false,
"message": "Невірний API ключ, аккаунт неактивний або IP адреса не дозволена",
"error_code": "AUTHENTICATION_FAILED"
}
Example response (404, Виплата не знайдена):
{
"success": false,
"message": "Заявку на виплату не знайдено",
"error_code": "PAYOUT_NOT_FOUND",
"sandbox_mode": false
}
Example response (500, Внутрішня помилка сервера):
{
"success": false,
"message": "Помилка при отриманні статусу заявки на виплату: Internal server error",
"error_code": "INTERNAL_ERROR",
"sandbox_mode": false
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішного запиту.
data
object
merchant_payout_id
string
ID виплати в системі мерчанта.
amount_received
number
Фактично отримана сума.
orders
string[]
Платежі, зараховані до виплати.
pricing
object
Поточний тариф виплати в USD.
sandbox_mode
boolean
Ознака тестового режиму.
Створення виплати
requires authentication
Створює нову заявку на виплату в P2P маркетплейсі.
Принцип роботи
- Перевірка унікальності - система перевіряє чи не існує виплати з таким
merchant_payout_id - Валідація суми - перевірка кратності суми кроку платежу та лімітів мерчанта
- Створення користувача - якщо користувач з
partner_user_idне існує, він буде створений автоматично - Оплата комісії - сума виплати конвертується в USD за актуальним курсом, після чого комісія згідно з тарифом списується з USD-балансу мерчанта
- Пошук плательщиків - система автоматично шукає користувачів готових здійснити оплату
- Webhook сповіщення - надсилається сповіщення про створення виплати (якщо налаштовано)
Валідація суми виплати
Сума виплати повинна бути кратна кроку платежу мерчанта.
Приклад: якщо крок платежу = 50, то допустимі суми:
- ✅ 50, 100, 150, 200, 250... 9950, 10000
- ❌ 75, 125, 1001, 2500.50
Також сума повинна відповідати лімітам:
- Мінімальна сума: отримується з налаштувань мерчанта
- Максимальна сума: отримується з налаштувань мерчанта
Для отримання актуальних лімітів використовуйте GET /api/v1/merchant/settings
Sandbox режим
У тестовому режимі:
- Всі операції помічаються як
is_sandbox: true - Не впливають на реальний баланс
- Автоматично підтверджуються платежі
- Ізольовані від production даних
Example request:
curl --request POST \
"https://api.p2p-market.net/api/v1/payout" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"partner_user_id\": \"user_12345\",
\"amount_total\": 1000,
\"currency\": \"UAH\",
\"recipient_card_number\": \"4111111111111111\",
\"recipient_card_holder_name\": \"Ivan Petrov\",
\"recipient_bank_name\": \"PrivatBank\",
\"wallet_address\": \"wallet-address\",
\"rate\": 41.5,
\"merchant_payout_id\": \"payout_67890\",
\"meta\": {
\"order_id\": \"123\",
\"description\": \"Виплата за послуги\"
},
\"metadata\": {
\"name\": \"Іван Петров\",
\"email\": \"[email protected]\",
\"telegram_id\": 123456789
},
\"min_payment_amount\": 100,
\"max_payment_amount\": 5000
}"
const url = new URL(
"https://api.p2p-market.net/api/v1/payout"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"partner_user_id": "user_12345",
"amount_total": 1000,
"currency": "UAH",
"recipient_card_number": "4111111111111111",
"recipient_card_holder_name": "Ivan Petrov",
"recipient_bank_name": "PrivatBank",
"wallet_address": "wallet-address",
"rate": 41.5,
"merchant_payout_id": "payout_67890",
"meta": {
"order_id": "123",
"description": "Виплата за послуги"
},
"metadata": {
"name": "Іван Петров",
"email": "[email protected]",
"telegram_id": 123456789
},
"min_payment_amount": 100,
"max_payment_amount": 5000
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/payout';
$response = $client->post(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'partner_user_id' => 'user_12345',
'amount_total' => 1000.0,
'currency' => 'UAH',
'recipient_card_number' => '4111111111111111',
'recipient_card_holder_name' => 'Ivan Petrov',
'recipient_bank_name' => 'PrivatBank',
'wallet_address' => 'wallet-address',
'rate' => 41.5,
'merchant_payout_id' => 'payout_67890',
'meta' => [
'order_id' => '123',
'description' => 'Виплата за послуги',
],
'metadata' => [
'name' => 'Іван Петров',
'email' => '[email protected]',
'telegram_id' => 123456789,
],
'min_payment_amount' => 100.0,
'max_payment_amount' => 5000.0,
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200, Успішне створення виплати):
{
"success": true,
"data": {
"id": 123,
"merchant_payout_id": "payout_67890",
"amount_total": 1000,
"amount_received": 0,
"currency": "UAH",
"status": "pending",
"recipient_card_number": "1234567890123456",
"recipient_card_holder_name": "Ivan Petrov",
"recipient_bank_name": "PrivatBank",
"min_payment_amount": 100,
"max_payment_amount": 5000,
"is_sandbox": false,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
},
"sandbox_mode": false
}
Example response (200, Створення в sandbox режимі):
{
"success": true,
"data": {
"id": 124,
"merchant_payout_id": "test_payout_123",
"amount_total": 500,
"amount_received": 0,
"currency": "UAH",
"status": "pending",
"recipient_card_number": "1234567890123456",
"recipient_card_holder_name": "Test User",
"recipient_bank_name": "Test Bank",
"min_payment_amount": null,
"max_payment_amount": null,
"is_sandbox": true,
"created_at": "2024-01-15T10:31:00Z",
"updated_at": "2024-01-15T10:31:00Z"
},
"sandbox_mode": true,
"sandbox_notice": "Тестова виплата - не впливає на реальний баланс"
}
Example response (400, Дублювання ID виплати):
{
"success": false,
"message": "Заявка з таким merchant_payout_id вже існує",
"error_code": "DUPLICATE_PAYOUT_ID",
"sandbox_mode": false
}
Example response (401, Невірний API ключ):
{
"success": false,
"message": "Невірний API ключ, аккаунт неактивний або IP адреса не дозволена",
"error_code": "AUTHENTICATION_FAILED"
}
Example response (422, Помилки валідації):
{
"success": false,
"message": "Помилки валідації",
"errors": {
"partner_user_id": [
"ID користувача у системі мерчанта є обов'язковим"
],
"amount_total": [
"Сума виплати повинна бути кратна кроку платежу 50 UAH. Допустимі суми: 50, 100, 150, 200, 250",
"Сума виплати не може бути меншою за 50 UAH"
],
"recipient_card_number": [
"Необхідно вказати або номер карти або адресу гаманця"
]
}
}
Example response (500, Внутрішня помилка сервера):
{
"success": false,
"message": "Помилка при створенні заявки на виплату: Internal server error",
"error_code": "INTERNAL_ERROR",
"sandbox_mode": false
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішного створення.
data
object
id
integer
ID виплати в P2P Market.
merchant_payout_id
string
ID виплати в системі мерчанта.
status
string
Поточний статус виплати.
pricing
object
Поточний тариф; комісія фактично розраховується при завершенні виплати.
sandbox_mode
boolean
Ознака тестового режиму.
Управління виплатами
Відновлення призупиненої виплати
requires authentication
Дозволяє користувачу відновити виплату, яка була призупинена через проблеми з картою. Відновлення доступне тільки для першого блокування карти.
Умови відновлення
- Виплата повинна мати статус
requires_verification - Це повинно бути перше блокування даної карти
- Користувач повинен бути власником виплати
Результат відновлення
- Статус виплати змінюється на
pending - Блокування помічається як вирішене користувачем
- Система продовжує пошук плательщиків
Example request:
curl --request POST \
"https://api.p2p-market.net/api/v1/payout-management/resume" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"merchant_payout_id\": \"payout_67890\",
\"partner_user_id\": \"user_12345\"
}"
const url = new URL(
"https://api.p2p-market.net/api/v1/payout-management/resume"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"merchant_payout_id": "payout_67890",
"partner_user_id": "user_12345"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/payout-management/resume';
$response = $client->post(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'merchant_payout_id' => 'payout_67890',
'partner_user_id' => 'user_12345',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200, Успішне відновлення виплати):
{
"success": true,
"message": "Виплату успішно відновлено",
"data": {
"payout_id": 123,
"status": "pending",
"restored_at": "2024-01-15T14:30:00Z",
"restored_by": "user"
}
}
Example response (400, Виплата не потребує відновлення):
{
"success": false,
"message": "Виплата не потребує відновлення або не може бути відновлена",
"error_code": "PAYOUT_NOT_RESTORABLE"
}
Example response (403, Відновлення недоступне):
{
"success": false,
"message": "Відновлення недоступне для цієї карти (можливе тільки для першого блокування)",
"error_code": "RESTORE_NOT_ALLOWED"
}
Example response (404, Виплата не знайдена):
{
"success": false,
"message": "Виплату не знайдено або вона не належить вказаному користувачу",
"error_code": "PAYOUT_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішного виконання.
message
string
Опис результату.
data
object
status
string
Статус виплати після відновлення.
Зміна карти
requires authentication
Дозволяє користувачу змінити карту отримувача для виплати. Якщо виплата була призупинена, після зміни карти виплата автоматично відновлюється.
Процес зміни карти
- Перевірка права на зміну карти
- Валідація нової карти
- Оновлення даних виплати
- Відновлення статусу виплати
Обмеження
- Нова карта не може співпадати зі старою
- Карта повинна пройти базову валідацію
Example request:
curl --request POST \
"https://api.p2p-market.net/api/v1/payout-management/change-card" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"merchant_payout_id\": \"payout_67890\",
\"new_card_number\": \"5168742012345678\",
\"new_card_holder_name\": \"IVAN PETROV\"
}"
const url = new URL(
"https://api.p2p-market.net/api/v1/payout-management/change-card"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"merchant_payout_id": "payout_67890",
"new_card_number": "5168742012345678",
"new_card_holder_name": "IVAN PETROV"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/payout-management/change-card';
$response = $client->post(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'merchant_payout_id' => 'payout_67890',
'new_card_number' => '5168742012345678',
'new_card_holder_name' => 'IVAN PETROV',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200, Успішна зміна карти):
{
"success": true,
"message": "Карту успішно змінено, виплату відновлено",
"data": {
"payout_id": 123,
"old_card": "1234567890123456",
"new_card": "5168742012345678",
"status": "pending",
"changed_at": "2024-01-15T14:45:00Z"
}
}
Example response (400, Однакова карта):
{
"success": false,
"message": "Нова карта не може співпадати з поточною",
"error_code": "SAME_CARD_NUMBER"
}
Example response (404, Виплата не знайдена):
{
"success": false,
"message": "Виплату не знайдено",
"error_code": "PAYOUT_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішного виконання.
message
string
Опис результату.
data
object
new_card
string
Новий номер картки.
status
string
Статус виплати після зміни.
Зміна статусу виплати
requires authentication
Дозволяє мерчанту змінювати статус виплати згідно з бізнес-правилами.
Інтелектуальна логіка зміни статусу
Система автоматично визначає фінальний статус на основі наявності платежів:
Скасування (cancelled):
- З "pending" →
cancelled(якщо немає платежів) абоpartially_paid(якщо є платежі) - З "requires_verification" →
cancelled(якщо немає платежів) абоpartially_paid(якщо є платежі) - З "cancelled" →
partially_paid(якщо є платежі, інакше залишаєтьсяcancelled) - З "partially_paid" → залишається
partially_paid(ідемпотентність)
Відновлення (pending):
- З "requires_verification" →
pending(з обробкою блокувань карт) - З "cancelled" →
pending - З "partially_paid" →
pending
Переваги інтелектуальної логіки
- ✅ Автоматичне визначення правильного статусу
- ✅ Запобігання втраті інформації про платежі
- ✅ Спрощений API для клієнтів
- ✅ Консистентність з веб-інтерфейсом мерчанта
Example request:
curl --request POST \
"https://api.p2p-market.net/api/v1/payout-management/change-status" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"merchant_payout_id\": \"payout_67890\",
\"new_status\": \"cancelled\"
}"
const url = new URL(
"https://api.p2p-market.net/api/v1/payout-management/change-status"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"merchant_payout_id": "payout_67890",
"new_status": "cancelled"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/payout-management/change-status';
$response = $client->post(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'merchant_payout_id' => 'payout_67890',
'new_status' => 'cancelled',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200, Скасування виплати без платежів):
{
"success": true,
"message": "Виплату скасовано",
"data": {
"payout_id": 123,
"old_status": "pending",
"final_status": "cancelled",
"action": "cancelled",
"has_payments": false,
"changed_at": "2024-01-15T14:30:00Z"
}
}
Example response (200, Скасування виплати з платежами):
{
"success": true,
"message": "Виплату переведено в статус 'Частково оплачено' (є платежі)",
"data": {
"payout_id": 123,
"old_status": "pending",
"final_status": "partially_paid",
"action": "cancelled",
"has_payments": true,
"amount_received": 500,
"changed_at": "2024-01-15T14:30:00Z"
}
}
Example response (200, Відновлення виплати):
{
"success": true,
"message": "Виплату відновлено до статусу 'В очікуванні'",
"data": {
"payout_id": 123,
"old_status": "cancelled",
"final_status": "pending",
"action": "pending",
"changed_at": "2024-01-15T14:30:00Z"
}
}
Example response (400, Неможлива зміна статусу):
{
"success": false,
"message": "Неможливо змінити статус виплати з 'completed' на 'cancelled'",
"error_code": "INVALID_ACTION"
}
Example response (404, Виплата не знайдена):
{
"success": false,
"message": "Виплату не знайдено або вона не належить вказаному користувачу",
"error_code": "PAYOUT_NOT_FOUND"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішного виконання.
message
string
Опис результату.
data
object
final_status
string
Фактичний статус після операції.
action
string
Запитана дія.
Платежі
Отримання статусу платежу
requires authentication
Повертає детальну інформацію про платіж (замовлення) за його ID. Цей метод використовує загальний API ключ мерчанта.
Життєвий цикл платежу та логіка підтвердження
new- Платіж створений, очікує оплатиpending- Платіж призначений плательщику, очікує підтвердженняpaid- Платіж оплачений, завантажено чек ✅confirmed- Платіж автоматично підтверджено через 24 години після статусу "paid" 🔒disputed- Відкрито спір по платежу ⚠️expired- Час на оплату вичерпаноcancelled- Платіж скасованийrefunded- Платіж повернено 💸
⚠️ Важливо: Правила оскарження платежів
24-годинне вікно оскарження:
- Після встановлення статусу
paidкористувачі мають 24 години для подання скарги - Через 24 години статус автоматично змінюється на
confirmed - Платежі зі статусом
confirmedне можуть бути оскаржені - При зміні статусу на
confirmedвідправляється webhookorder.confirmed
Повернення коштів:
- Якщо користувач надав достатні докази того, що кошти не надійшли, платіж може бути переведений в статус
refunded
Особливості Sandbox режиму
У тестовому режимі:
- Платежі автоматично підтверджуються без ручної перевірки
- Додаються спеціальні мітки
sandbox_auto_confirm: true - Не впливають на реальні баланси
Приклад використання (PHP)
// Простий запит статусу платежу
$paymentId = 12345; // ID платежу отриманий при створенні
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => '{API_BASE_URL}/api/v1/order/status?payment_id=' . $paymentId,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY']
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
if ($data['success']) {
$status = $data['data']['status'];
$amount = $data['data']['amount'];
switch ($status) {
case 'pending':
echo "Платіж очікує оплати на суму {$amount} UAH";
break;
case 'paid':
echo "Платіж оплачений, очікує підтвердження";
break;
case 'confirmed':
echo "Платіж успішно завершений!";
break;
case 'expired':
echo "Термін оплати вичерпано";
break;
default:
echo "Статус платежу: {$status}";
}
} else {
echo "Помилка: " . $data['message'];
}
Безпека
- Кожен мерчант може отримувати інформацію тільки про власні платежі
- Перевіряється відповідність sandbox/production режимів
- Логуються всі запити для аудиту
Example request:
curl --request GET \
--get "https://api.p2p-market.net/api/v1/order/status?payment_id=456" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.p2p-market.net/api/v1/order/status"
);
const params = {
"payment_id": "456",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/order/status';
$response = $client->get(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'payment_id' => '456',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200, Успішне отримання статусу платежу):
{
"success": true,
"data": {
"id": 456,
"merchant_payment_id": "ORDER_123456",
"status": "confirmed",
"currency": "UAH",
"amount": 500.3,
"merchant_user_id": "customer_123",
"created_at": "2024-01-15T11:00:00.000000Z",
"completed_at": "2024-01-15T11:30:00.000000Z",
"has_overpayment": false,
"recipient_card_number": "5375 41** **** 1234",
"merchant_payout_id": "payout_67890",
"receipts": [
{
"id": 789,
"official_url": "https://bank.example/receipt/789",
"receipt_url": "{RECEIPT_URL}",
"match_score": 95.5,
"receipt_number": "12345",
"created_at": "2024-01-15T11:15:00.000000Z"
}
],
"disputes": [],
"sandbox_mode": false
}
}
Example response (200, Статус sandbox платежу):
{
"success": true,
"data": {
"id": 457,
"merchant_payment_id": "TEST_ORDER_123",
"status": "confirmed",
"currency": "UAH",
"amount": 250,
"merchant_user_id": "test_customer_456",
"created_at": "2024-01-15T10:32:00.000000Z",
"completed_at": "2024-01-15T10:32:00.000000Z",
"has_overpayment": false,
"recipient_card_number": "1234567890123456",
"merchant_payout_id": "test_payout_123",
"receipts": [],
"disputes": [],
"sandbox_mode": true
}
}
Example response (200, Платіж в процесі):
{
"success": true,
"data": {
"id": 458,
"merchant_payment_id": "ORDER_789",
"status": "pending",
"currency": "UAH",
"amount": 300,
"merchant_user_id": "customer_789",
"created_at": "2024-01-15T12:00:00.000000Z",
"completed_at": null,
"has_overpayment": false,
"recipient_card_number": null,
"merchant_payout_id": null,
"receipts": [],
"disputes": [],
"sandbox_mode": false
}
}
Example response (200, Платіж з переплатою):
{
"success": true,
"data": {
"id": 459,
"merchant_payment_id": "ORDER_999",
"status": "paid",
"currency": "UAH",
"amount": 1000,
"merchant_user_id": "customer_999",
"created_at": "2024-01-15T13:00:00.000000Z",
"completed_at": null,
"has_overpayment": true,
"recipient_card_number": "5375 41** **** 5678",
"merchant_payout_id": "payout_999",
"receipts": [
{
"id": 101,
"official_url": "https://bank.example/receipt/101",
"receipt_url": "{RECEIPT_URL}",
"match_score": 88.2,
"receipt_number": "98765",
"created_at": "2024-01-15T13:05:00.000000Z"
}
],
"disputes": [],
"sandbox_mode": false
}
}
Example response (200, Платіж зі спором):
{
"success": true,
"data": {
"id": 460,
"merchant_payment_id": "ORDER_DISPUTE",
"status": "disputed",
"currency": "UAH",
"amount": 750,
"merchant_user_id": "customer_dispute",
"created_at": "2024-01-15T09:00:00.000000Z",
"completed_at": null,
"has_overpayment": false,
"recipient_card_number": "4441 11** **** 9999",
"merchant_payout_id": "payout_dispute",
"receipts": [
{
"id": 102,
"official_url": "https://bank.example/receipt/102",
"receipt_url": "{RECEIPT_URL}",
"match_score": 45.3,
"receipt_number": "11111",
"created_at": "2024-01-15T09:15:00.000000Z"
}
],
"disputes": [
{
"id": 15,
"status": "open",
"reason": "Amount mismatch",
"initiator": "system",
"created_at": "2024-01-15T09:30:00.000000Z",
"resolved_at": null
}
],
"sandbox_mode": false
}
}
Example response (400, Невідповідність режимів):
{
"success": false,
"message": "Невідповідність режимів. Запит в production режимі, але замовлення створено в sandbox режимі",
"error_code": "MODE_MISMATCH",
"sandbox_mode": false
}
Example response (401, Невірний API ключ):
{
"success": false,
"message": "Невірний API ключ, аккаунт неактивний або IP адреса не дозволена",
"error_code": "AUTHENTICATION_FAILED"
}
Example response (403, Платіж не належить мерчанту):
{
"success": false,
"message": "Платіж не належить цьому мерчанту",
"error_code": "ACCESS_DENIED",
"sandbox_mode": false
}
Example response (404, Платіж не знайдений):
{
"success": false,
"message": "Платіж не знайдено",
"error_code": "ORDER_NOT_FOUND",
"sandbox_mode": false
}
Example response (500, Внутрішня помилка сервера):
{
"success": false,
"message": "Помилка при отриманні статусу платежу: Internal server error",
"error_code": "INTERNAL_ERROR",
"sandbox_mode": false
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішного запиту.
data
object
id
integer
ID платежу.
merchant_payment_id
string
ID платежу в системі мерчанта.
status
string
Поточний статус платежу.
receipts
string[]
Пов'язані квитанції.
disputes
string[]
Пов'язані спори.
Отримати доступні ліміти для створення платежу
requires authentication
Перевіряє можливість створення платежу та повертає доступні ліміти. Автоматично створює користувача, якщо він не існує.
Особливості
- Автоматичне створення користувача: При першому запиті користувач буде створений автоматично
- Перевірка лімітів: Система перевіряє чи може користувач створити новий платіж
- Налаштування мерчанта: Повертає налаштування сум та банків для вашого мерчанта
Приклад використання (PHP)
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => '{API_BASE_URL}/api/v1/order-limits?partner_user_id=customer_123&amount=500',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['X-API-Key: YOUR_API_KEY']
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
if ($data['success'] && $data['data']['can_create_payment']) {
echo "Можна створити платіж на суму: " . $data['data']['limits']['max_amount'];
} else {
echo "Помилки: " . implode(', ', $data['data']['errors']);
}
Example request:
curl --request GET \
--get "https://api.p2p-market.net/api/v1/order-limits?partner_user_id=customer_123&amount=500" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"amount\": 27,
\"partner_user_id\": \"n\"
}"
const url = new URL(
"https://api.p2p-market.net/api/v1/order-limits"
);
const params = {
"partner_user_id": "customer_123",
"amount": "500",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"amount": 27,
"partner_user_id": "n"
};
fetch(url, {
method: "GET",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/order-limits';
$response = $client->get(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'query' => [
'partner_user_id' => 'customer_123',
'amount' => '500',
],
'json' => [
'amount' => 27,
'partner_user_id' => 'n',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200, Успішна перевірка лімітів):
{
"success": true,
"data": {
"merchant_id": 1,
"merchant_name": "Тестовий мерчант",
"can_create_payment": true,
"partner_user_id": "customer_123",
"limits": {
"currency": "UAH",
"min_amount": 50,
"max_amount": 10000,
"payment_step": 50,
"available_amounts": [
50,
100,
150,
200,
500,
1000
],
"allowed_banks": {
"monobank": "Monobank",
"privatbank": "PrivatBank",
"abank": "A-Bank"
}
},
"errors": []
}
}
Example response (200, Платіж неможливий через обмеження):
{
"success": true,
"data": {
"merchant_id": 1,
"merchant_name": "Тестовий мерчант",
"can_create_payment": false,
"partner_user_id": "customer_123",
"limits": null,
"errors": [
"У вас вже є активний платіж. Завершіть або скасуйте його для створення нового."
]
}
}
Example response (401, Невірний API ключ):
{
"success": false,
"message": "Невірний API ключ, аккаунт неактивний або IP адреса не дозволена",
"error_code": "AUTHENTICATION_FAILED"
}
Example response (422, Помилка валідації):
{
"success": false,
"message": "Помилки валідації",
"error_code": "VALIDATION_ERROR",
"errors": {
"partner_user_id": [
"Поле partner_user_id є обов'язковим."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішного запиту.
data
object
can_create_payment
boolean
Чи можна створити платіж.
limits
object
Актуальні ліміти та банки або null.
errors
string[]
Бізнес-причини, через які платіж недоступний.
Створити платіж
requires authentication
Створює новий платіж з автоматичним вибором карти для переказу. Автоматично створює або оновлює користувача з переданими даними.
Принцип роботи
- Створення/оновлення користувача - Якщо користувач не існує, він буде створений з переданими метаданими
- Валідація даних - Перевірка суми, банку та інших параметрів
- Автоматичний вибір карти - Система автоматично вибирає найкращу карту для переказу
- Створення замовлення - Формується замовлення з інструкціями для клієнта
- Повернення даних - Отримуєте всю необхідну інформацію для показу клієнту
Приклад використання (PHP)
$data = [
'amount' => 500,
'bank' => 'monobank',
'partner_user_id' => 'customer_123',
'merchant_payment_id' => 'ORDER_' . time(),
'description' => 'Оплата за товар',
'metadata' => [
'name' => 'Іван Петров',
'email' => '[email protected]'
]
];
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => '{API_BASE_URL}/api/v1/order',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($data),
CURLOPT_HTTPHEADER => [
'X-API-Key: YOUR_API_KEY',
'Content-Type: application/json'
]
]);
$response = curl_exec($ch);
$result = json_decode($response, true);
if ($result['success']) {
$paymentUrl = $result['data']['payment_url'];
$redirectUrl = $result['data']['redirect_url'];
$cardNumber = $result['data']['payout_details']['card_number'];
echo "Платіж створено! Переведіть {$data['amount']} UAH на карту {$cardNumber}";
echo "Інструкції: {$paymentUrl}";
echo "Перенаправити користувача: {$redirectUrl}";
} else {
echo "Помилка: " . $result['message'];
}
Example request:
curl --request POST \
"https://api.p2p-market.net/api/v1/order" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"amount\": 500,
\"bank\": \"monobank\",
\"partner_user_id\": \"customer_123\",
\"merchant_payment_id\": \"ORDER_123456\",
\"description\": \"Оплата за замовлення #123456\",
\"redirect_url\": \"https:\\/\\/merchant.example\\/orders\\/ORDER_123456\",
\"metadata\": {
\"name\": \"Іван Петров\",
\"email\": \"[email protected]\"
}
}"
const url = new URL(
"https://api.p2p-market.net/api/v1/order"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"amount": 500,
"bank": "monobank",
"partner_user_id": "customer_123",
"merchant_payment_id": "ORDER_123456",
"description": "Оплата за замовлення #123456",
"redirect_url": "https:\/\/merchant.example\/orders\/ORDER_123456",
"metadata": {
"name": "Іван Петров",
"email": "[email protected]"
}
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/order';
$response = $client->post(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'amount' => 500.0,
'bank' => 'monobank',
'partner_user_id' => 'customer_123',
'merchant_payment_id' => 'ORDER_123456',
'description' => 'Оплата за замовлення #123456',
'redirect_url' => 'https://merchant.example/orders/ORDER_123456',
'metadata' => [
'name' => 'Іван Петров',
'email' => '[email protected]',
],
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (201, Успішне створення платежу):
{
"success": true,
"data": {
"id": 12345,
"merchant_payment_id": "ORDER_123456",
"amount": 500,
"currency": "UAH",
"status": "new",
"merchant_id": 1,
"partner_user_id": "customer_123",
"payout_details": {
"card_number": "5375 41** **** 1234",
"card_holder": "ІВАН ПЕТРОВ",
"bank_name": "Monobank"
},
"requires_bank_selection": false,
"payment_url": "https://app.example/deposit/instructions/12345",
"redirect_url": "https://app.example/auth?token=auth_token&page=order&orderId=12345",
"expires_at": "2026-07-24T15:30:00.000Z",
"instructions": "Переведіть зазначену суму на карту та завантажте чек про оплату"
}
}
Example response (201, Успішне створення платежу з вибором банку користувачем):
{
"success": true,
"data": {
"id": 12345,
"merchant_payment_id": "ORDER_123456",
"amount": 500,
"currency": "UAH",
"status": "new",
"merchant_id": 1,
"partner_user_id": "customer_123",
"payout_details": null,
"requires_bank_selection": true,
"payment_url": "https://app.example/orders/12345",
"redirect_url": "https://app.example/auth?token=auth_token&page=order&orderId=12345",
"expires_at": "2026-08-26T11:00:00.000Z"
}
}
Example response (401, Невірний API ключ):
{
"success": false,
"message": "Невірний API ключ, аккаунт неактивний або IP адреса не дозволена",
"error_code": "AUTHENTICATION_FAILED"
}
Example response (422, Помилка валідації):
{
"success": false,
"errors": [
"Поле amount є обов'язковим."
],
"code": "VALIDATION_ERROR"
}
Example response (422, Неправильний банк):
{
"success": false,
"errors": [
"Вибраний банк не підтримується"
],
"code": "INVALID_BANK"
}
Example response (503, Немає доступних карт):
{
"success": false,
"errors": [
"Немає доступних карт для створення платежу"
],
"code": "NO_AVAILABLE_CARDS"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішного створення.
data
object
id
integer
ID платежу в P2P Market.
status
string
Початковий статус платежу.
payout_details
object|null
Реквізити для переказу або null до вибору банку.
requires_bank_selection
boolean
Чи повинен користувач вибрати банк за посиланням.
redirect_url
string
URL для переходу користувача; для платежу без банку scoped-посилання діє 24 години від створення замовлення.
expires_at
string
Дедлайн оплати, що для платежу без банку настає через 60 хвилин від створення замовлення.
Верифікація квитанцій
Верифікація квитанції (платний продукт).
requires authentication
Вартість однієї верифікації — 0,01 USD за замовчуванням (точне значення визначається конфігурацією продукту). У sandbox-режимі плата не списується. Максимальний розмір файлу — 10 МБ (якщо конфігурацію не змінено).
Example request:
curl --request POST \
"https://api.p2p-market.net/api/v1/receipt/verify" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "mode=verify"\
--form "currency=UAH"\
--form "expected[amount]=4326.41688"\
--form "expected[date]=architecto"\
--form "expected[card_number]=architecto"\
--form "file=@/tmp/phpzo49xU" const url = new URL(
"https://api.p2p-market.net/api/v1/receipt/verify"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('mode', 'verify');
body.append('currency', 'UAH');
body.append('expected[amount]', '4326.41688');
body.append('expected[date]', 'architecto');
body.append('expected[card_number]', 'architecto');
body.append('file', document.querySelector('input[name="file"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/receipt/verify';
$response = $client->post(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'multipart/form-data',
'Accept' => 'application/json',
],
'multipart' => [
[
'name' => 'mode',
'contents' => 'verify'
],
[
'name' => 'currency',
'contents' => 'UAH'
],
[
'name' => 'expected[amount]',
'contents' => '4326.41688'
],
[
'name' => 'expected[date]',
'contents' => 'architecto'
],
[
'name' => 'expected[card_number]',
'contents' => 'architecto'
],
[
'name' => 'file',
'contents' => fopen('/tmp/phpzo49xU', 'r')
],
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200, Квитанцію оброблено):
{
"success": true,
"data": {
"verification_id": 321,
"mode": "verify",
"status": "verified",
"is_original": true,
"signature_valid": true,
"match": null,
"parsed_data": {
"amount": 500,
"currency": "UAH"
},
"cost": 0.01,
"currency_cost": "USD",
"balance_after": 19.97
}
}
Example response (402, Недостатньо коштів):
{
"success": false,
"message": "Недостатньо коштів",
"error_code": "INSUFFICIENT_BALANCE"
}
Example response (422, Акаунт балансу не знайдено):
{
"success": false,
"message": "Для мерчанта не знайдено акаунт балансу",
"error_code": "BALANCE_ACCOUNT_NOT_FOUND"
}
Example response (502, Сервіс тимчасово недоступний):
{
"success": false,
"message": "Сервіс верифікації тимчасово недоступний",
"error_code": "VERIFICATION_UNAVAILABLE"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішної обробки запиту.
data
object
verification_id
integer
ID операції верифікації.
status
string
Статус: verified, rejected, needs_review або error.
cost
number
Списана вартість у USD.
balance_after
number
Доступний баланс після списання.
Налаштування мерчанта
Отримати налаштування мерчанта
requires authentication
Повертає базові налаштування мерчанта для інтеграції.
Інформація що повертається
- Валюта - основна валюта мерчанта
- Ліміти сум - мінімальна/максимальна суми платежів
- Крок платежу - на яку суму можна збільшувати платіж
- Дозволені банки - актуальний список усіх доступних банків для валюти та країни мерчанта
- Тарифи - фіксована ціна верифікації поповнення та відсоток комісії за виплату
Використання
Ці налаштування необхідні для:
- Валідації сум перед створенням виплат
- Відображення доступних банків у користувацькому інтерфейсі
- Розрахунку комісій
- Налаштування логіки автопідтвердження
Example request:
curl --request GET \
--get "https://api.p2p-market.net/api/v1/merchant/settings" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.p2p-market.net/api/v1/merchant/settings"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/merchant/settings';
$response = $client->get(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200, Успішне отримання налаштувань):
{
"success": true,
"data": {
"currency": "UAH",
"min_payment_amount": 50,
"max_payment_amount": 50000,
"payment_step": 10,
"allowed_banks": {
"monobank": "Monobank",
"privatbank": "PrivatBank"
},
"pricing": {
"settlement_currency": "USD",
"topup_verification_fee": 0.03,
"payout_fee_percentage": 1.5,
"payout_conversion": "platform_rate_at_charge_time",
"rounding_precision": 2
}
}
}
Example response (401, Невірний API ключ):
{
"success": false,
"message": "Невірний API ключ, аккаунт неактивний або IP адреса не дозволена",
"error_code": "AUTHENTICATION_FAILED"
}
Example response (404, Мерчант не знайдений):
{
"success": false,
"message": "Мерчант не знайдений"
}
Example response (500, Внутрішня помилка сервера):
{
"success": false,
"message": "Помилка при отриманні налаштувань: Internal server error"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішного запиту.
data
object
allowed_banks
object
Актуальні коди та назви банків.
pricing
object
Поточні тарифи мерчанта в USD.
topup_verification_fee
number
Ціна успішного поповнення.
payout_fee_percentage
number
Відсоток тарифу виплати.
Отримати суму доступних платежів для мерчанта
requires authentication
Повертає загальну суму доступних коштів для прийому платежів з урахуванням зайнятих виплат та групових налаштувань мерчанта.
Інформація що повертається
- total_available_amount - загальна доступна сума для прийому платежів
- available_payouts_count - кількість доступних виплат
- currency - валюта мерчанта
- includes_group - чи враховуються виплати з групи мерчантів
Використання
Цей endpoint дозволяє мерчантам:
- Перевіряти скільки коштів можна прийняти на даний момент
- Розуміти чи потрібно терміново створювати нові виплати
- Планувати обсяги прийому платежів
- Моніторити ліквідність в реальному часі
Example request:
curl --request GET \
--get "https://api.p2p-market.net/api/v1/merchant/available-payment-amounts" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.p2p-market.net/api/v1/merchant/available-payment-amounts"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/merchant/available-payment-amounts';
$response = $client->get(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200, Успішне отримання доступних сум):
{
"success": true,
"data": {
"total_available_amount": 125000,
"available_payouts_count": 15,
"currency": "UAH",
"includes_group": true,
"breakdown": {
"own_payouts": {
"count": 8,
"amount": 75000
},
"group_payouts": {
"count": 7,
"amount": 50000
}
}
}
}
Example response (401, Невірний API ключ):
{
"success": false,
"message": "Невірний API ключ, аккаунт неактивний або IP адреса не дозволена",
"error_code": "AUTHENTICATION_FAILED"
}
Example response (404, Мерчант не знайдений):
{
"success": false,
"message": "Мерчант не знайдений"
}
Example response (500, Внутрішня помилка сервера):
{
"success": false,
"message": "Помилка при отриманні доступних сум: Internal server error"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішного запиту.
data
object
total_available_amount
number
Загальна доступна сума.
available_payouts_count
integer
Кількість доступних виплат.
breakdown
object
Розподіл власних і групових виплат.
Вебхуки
Webhook надсилається як JSON-об'єкт без додаткової обгортки. Тип події
міститься в заголовку X-Event-Type, а X-Signature — це HMAC-SHA256 від
точних байтів JSON-тіла з API-ключем мерчанта як секретом.
Інформація про webhook-контракт
requires authentication
Невдала доставка повторюється кожні 15 хвилин. Загальна кількість спроб, включно з першою, — не більше п'яти. Обробник мерчанта має повертати будь-який HTTP-статус 2xx та бути ідемпотентним.
Example request:
curl --request GET \
--get "https://api.p2p-market.net/api/v1/webhooks/info" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.p2p-market.net/api/v1/webhooks/info"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/webhooks/info';
$response = $client->get(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
events
object
Події, які може надсилати платформа.
headers
object
Обов'язкові HTTP-заголовки webhook.
retry_policy
object
Політика повторних доставок.
Приклад webhook платежу
requires authentication
Example request:
curl --request GET \
--get "https://api.p2p-market.net/api/v1/webhooks/examples/payment" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.p2p-market.net/api/v1/webhooks/examples/payment"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/webhooks/examples/payment';
$response = $client->get(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
ID платежу в P2P Market.
merchant_payment_id
string
ID платежу в системі мерчанта.
status
string
Поточний статус платежу.
receipts
string[]
Квитанції, пов'язані з платежем.
Приклад webhook виплати
requires authentication
Example request:
curl --request GET \
--get "https://api.p2p-market.net/api/v1/webhooks/examples/payout" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.p2p-market.net/api/v1/webhooks/examples/payout"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/webhooks/examples/payout';
$response = $client->get(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
id
integer
ID виплати в P2P Market.
merchant_payout_id
string
ID виплати в системі мерчанта.
amount_received
number
Уже отримана сума.
orders
string[]
Платежі, пов'язані з виплатою.
Рекомендований порядок інтеграції
requires authentication
Example request:
curl --request GET \
--get "https://api.p2p-market.net/api/v1/webhooks/integration-flow" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.p2p-market.net/api/v1/webhooks/integration-flow"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/webhooks/integration-flow';
$response = $client->get(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
integration_flow
string[]
Послідовність інтеграційних кроків.
requirements
string[]
Обов'язкові вимоги до реалізації.
Алгоритм перевірки підпису
requires authentication
Обчисліть hash_hmac('sha256', $rawJsonBody, $apiKey) для незміненого
тіла запиту та порівняйте результат із X-Signature через hash_equals.
Example request:
curl --request GET \
--get "https://api.p2p-market.net/api/v1/webhooks/signature-verification" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.p2p-market.net/api/v1/webhooks/signature-verification"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/webhooks/signature-verification';
$response = $client->get(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
algorithm
string
Алгоритм підпису.
signed_content
string
Дані, які підписуються.
secret
string
Секрет для HMAC.
Надіслати тестовий webhook
requires authentication
Тест надсилається лише на URL webhook_payment або webhook_payout,
попередньо налаштований для поточного мерчанта. Довільний URL не
приймається, щоб endpoint не можна було використати для SSRF.
Example request:
curl --request POST \
"https://api.p2p-market.net/api/v1/webhooks/test" \
--header "X-API-Key: your-api-key-here" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"data_type\": \"order\",
\"event_type\": \"order.paid\"
}"
const url = new URL(
"https://api.p2p-market.net/api/v1/webhooks/test"
);
const headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"data_type": "order",
"event_type": "order.paid"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/v1/webhooks/test';
$response = $client->post(
$url,
[
'headers' => [
'X-API-Key' => 'your-api-key-here',
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
'json' => [
'data_type' => 'order',
'event_type' => 'order.paid',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200):
{
"success": true,
"message": "Тестовий webhook надіслано",
"data": {
"success": true,
"status_code": 204,
"response_time_ms": 125,
"event_type": "order.paid"
}
}
Example response (422):
{
"success": false,
"message": "Помилки валідації",
"error_code": "VALIDATION_ERROR",
"errors": {
"event_type": [
"Подія не відповідає типу даних"
]
}
}
Example response (502):
{
"success": false,
"message": "Отримувач webhook повернув помилку",
"error_code": "WEBHOOK_DELIVERY_FAILED",
"data": {
"success": false,
"status_code": 500,
"response_time_ms": 125,
"event_type": "order.paid"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішної доставки.
data
object
status_code
integer
HTTP-статус відповіді отримувача.
response_time_ms
integer
Тривалість запиту в мілісекундах.
Банки
Отримати актуальні банки для валюти
Повертає динамічний каталог усіх активних банків, доданих для валюти. Список, доступний конкретному мерчанту або користувачу, може бути вужчим.
Example request:
curl --request GET \
--get "https://api.p2p-market.net/api/currencies/UAH/banks" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.p2p-market.net/api/currencies/UAH/banks"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());$client = new \GuzzleHttp\Client();
$url = 'https://api.p2p-market.net/api/currencies/UAH/banks';
$response = $client->get(
$url,
[
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
],
]
);
$body = $response->getBody();
print_r(json_decode((string) $body));Example response (200):
{
"success": true,
"data": {
"monobank": "Monobank",
"privatbank": "PrivatBank"
}
}
Example response (404):
{
"success": false,
"message": "Валюта XYZ не підтримується",
"error_code": "CURRENCY_NOT_SUPPORTED"
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Response
Response Fields
success
boolean
Ознака успішного запиту.
data
object
Об'єкт код банку → назва банку.