MENU navbar-image

Introduction

Інтеграція прийому поповнень і створення виплат через P2P-обмін.

P2P Market API

P2P Market автоматично поєднує користувачів, які заводять кошти, з користувачами, які хочуть їх вивести: платник переказує кошти безпосередньо на реквізити активної виплати, а платформа зіставляє операції та оновлює їхні статуси.

Базовий сценарій

  1. Мерчант створює виплату через POST /api/v1/payout.
  2. Для користувача створюється тимчасовий URL через POST /api/v1/auth/token.
  3. Користувач створює платіж і переказує кошти на надані реквізити.
  4. Платформа перевіряє оплату, зараховує її до виплати та надсилає webhook.
  5. Мерчант обробляє 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 або логах.

Банки та ліміти

Платформа підтримує всі актуальні банки, доступні для відповідної валюти й країни. Каталог динамічний, тому не зберігайте перелік банків у коді:

Фактичний список може бути вужчим через валюту, налаштування мерчанта, користувацькі обмеження або тимчасову недоступність реквізитів.

Тарифи

Розрахункова валюта комісій — USD.

Формула комісії за виплату:

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-ключі є чутливими даними. Не записуйте їх у відкриті логи, обмежуйте доступ за принципом найменших привілеїв і зберігайте лише стільки, скільки потрібно для операції та законних вимог.

Зміни й сумісність

Актуальний стабільний контракт розміщено в OpenAPI-файлі цієї документації. Несумісні зміни мають виходити в новій версії API; deprecated endpoint-и позначаються в документації до видалення.

Зміни від 24.07.2026:

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 системи.

Принцип роботи

  1. Створення токену - генерується унікальний токен з терміном дії
  2. Створення/оновлення користувача - система знаходить існуючого користувача або створює нового
  3. Збереження дати реєстрації - якщо передано partner_registered_at, дата зберігається у профілі користувача
  4. Перенаправлення - користувач переходить по auth_url для авторизації
  5. Автоматичний вхід - система автоматично авторизує користувача
  6. Доступ до інтерфейсу - користувач отримує доступ до веб-інтерфейсу

Сценарії використання

Безпека

📅 Дата реєстрації користувача

Параметр partner_registered_at дозволяє передати дату реєстрації користувача в системі партнера. Ця дата використовується для:

Якщо параметр не передано, використовується дата створення запису в нашій системі (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"
}
 

Request   

POST api/v1/auth/token

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

partner_user_id   string   

ID користувача в системі мерчанта. Example: user_12345

redirect_url   string  optional  

URL для перенаправлення після авторизації. Example: https://yoursite.com/dashboard

metadata   object  optional  

Дані користувача для створення або оновлення профілю.

email   string  optional  

Email користувача. Example: [email protected]

name   string  optional  

Ім'я користувача. Example: Іван Петров

telegram_id   integer  optional  

Telegram ID користувача. Example: 123456789

partner_registered_at   date  optional  

Дата реєстрації користувача в системі партнера. Example: 2025-01-15 10:30:00

expires_in_minutes   integer  optional  

Час життя токену в хвилинах (за замовчуванням 60). Example: 120

partner_registered_at   date  optional  

Дата реєстрації користувача в системі партнера (формат: Y-m-d H:i:s або Y-m-d). Example: 2024-01-15 10:30:00

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.

Можливі статуси виплати

Додаткова інформація

Відповідь містить детальну інформацію про:

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
}
 

Request   

GET api/v1/payout/status

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

merchant_payout_id   string   

ID виплати в системі мерчанта. Example: payout_67890

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 маркетплейсі.

Принцип роботи

  1. Перевірка унікальності - система перевіряє чи не існує виплати з таким merchant_payout_id
  2. Валідація суми - перевірка кратності суми кроку платежу та лімітів мерчанта
  3. Створення користувача - якщо користувач з partner_user_id не існує, він буде створений автоматично
  4. Оплата комісії - сума виплати конвертується в USD за актуальним курсом, після чого комісія згідно з тарифом списується з USD-балансу мерчанта
  5. Пошук плательщиків - система автоматично шукає користувачів готових здійснити оплату
  6. Webhook сповіщення - надсилається сповіщення про створення виплати (якщо налаштовано)

Валідація суми виплати

Сума виплати повинна бути кратна кроку платежу мерчанта.

Приклад: якщо крок платежу = 50, то допустимі суми:

Також сума повинна відповідати лімітам:

Для отримання актуальних лімітів використовуйте GET /api/v1/merchant/settings

Sandbox режим

У тестовому режимі:

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
}
 

Request   

POST api/v1/payout

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

partner_user_id   string   

ID користувача в системі мерчанта. Максимум 191 символ. Example: user_12345

amount_total   number   

Сума виплати. Має відповідати актуальним лімітам і кроку з GET /api/v1/merchant/settings. Example: 1000

currency   string   

Валюта виплати (3 символи); має збігатися з валютою мерчанта. Example: UAH

recipient_card_number   string  optional  

Номер картки отримувача. Обов'язковий, якщо не передано wallet_address. Example: 4111111111111111

recipient_card_holder_name   string  optional  

Ім'я власника карти. Обов'язкове якщо вказано номер карти. Example: Ivan Petrov

recipient_bank_name   string  optional  

Назва банку. Визначається автоматично по номеру карти. Example: PrivatBank

wallet_address   string  optional  

Адреса гаманця. Альтернатива номеру картки; підтримувані мережу й валюту потрібно погодити до інтеграції. Example: wallet-address

rate   number  optional  

Довідковий курс мерчанта; це не курс конвертації комісії. Example: 41.5

merchant_payout_id   string   

Унікальний ID виплати в системі мерчанта. Максимум 191 символ. Example: payout_67890

meta   object  optional  

Додаткові дані виплати (опціонально).

metadata   object  optional  

Дані користувача для створення або оновлення профілю (опціонально).

name   string  optional  

Ім'я користувача. Example: Іван Петров

email   string  optional  

Email користувача. Example: [email protected]

telegram_id   integer  optional  

Telegram ID користувача. Example: 123456789

min_payment_amount   number  optional  

Мінімальна сума одного платежу на цю виплату (опціонально). Якщо не вказано — без обмежень. Останній платіж може бути меншим, якщо залишок виплати менший за мінімум. Example: 100

max_payment_amount   number  optional  

Максимальна сума одного платежу на цю виплату (опціонально). Якщо не вказано — без обмежень. Example: 5000

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

Дозволяє користувачу відновити виплату, яка була призупинена через проблеми з картою. Відновлення доступне тільки для першого блокування карти.

Умови відновлення

Результат відновлення

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"
}
 

Request   

POST api/v1/payout-management/resume

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

merchant_payout_id   string   

ID виплати в системі мерчанта. Example: payout_67890

partner_user_id   string   

ID користувача в системі мерчанта. Example: user_12345

Response

Response Fields

success   boolean   

Ознака успішного виконання.

message   string   

Опис результату.

data   object   
status   string   

Статус виплати після відновлення.

Зміна карти

requires authentication

Дозволяє користувачу змінити карту отримувача для виплати. Якщо виплата була призупинена, після зміни карти виплата автоматично відновлюється.

Процес зміни карти

  1. Перевірка права на зміну карти
  2. Валідація нової карти
  3. Оновлення даних виплати
  4. Відновлення статусу виплати

Обмеження

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"
}
 

Request   

POST api/v1/payout-management/change-card

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

merchant_payout_id   string   

ID виплати в системі мерчанта. Example: payout_67890

new_card_number   string   

Новий номер карти (16 цифр). Example: 5168742012345678

new_card_holder_name   string   

Ім'я власника нової карти. Example: IVAN PETROV

Response

Response Fields

success   boolean   

Ознака успішного виконання.

message   string   

Опис результату.

data   object   
new_card   string   

Новий номер картки.

status   string   

Статус виплати після зміни.

Зміна статусу виплати

requires authentication

Дозволяє мерчанту змінювати статус виплати згідно з бізнес-правилами.

Інтелектуальна логіка зміни статусу

Система автоматично визначає фінальний статус на основі наявності платежів:

Скасування (cancelled):

Відновлення (pending):

Переваги інтелектуальної логіки

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"
}
 

Request   

POST api/v1/payout-management/change-status

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

merchant_payout_id   string   

ID виплати в системі мерчанта. Example: payout_67890

new_status   string   

Дія над виплатою. Може бути: cancelled (скасувати), pending (відновити). Example: cancelled

Response

Response Fields

success   boolean   

Ознака успішного виконання.

message   string   

Опис результату.

data   object   
final_status   string   

Фактичний статус після операції.

action   string   

Запитана дія.

Платежі

Отримання статусу платежу

requires authentication

Повертає детальну інформацію про платіж (замовлення) за його ID. Цей метод використовує загальний API ключ мерчанта.

Життєвий цикл платежу та логіка підтвердження

  1. new - Платіж створений, очікує оплати
  2. pending - Платіж призначений плательщику, очікує підтвердження
  3. paid - Платіж оплачений, завантажено чек ✅
  4. confirmed - Платіж автоматично підтверджено через 24 години після статусу "paid" 🔒
  5. disputed - Відкрито спір по платежу ⚠️
  6. expired - Час на оплату вичерпано
  7. cancelled - Платіж скасований
  8. refunded - Платіж повернено 💸

⚠️ Важливо: Правила оскарження платежів

24-годинне вікно оскарження:

Повернення коштів:

Особливості Sandbox режиму

У тестовому режимі:

Приклад використання (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'];
}

Безпека

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
}
 

Request   

GET api/v1/order/status

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

payment_id   string   

ID платежу для отримання статусу. Example: 456

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 є обов'язковим."
        ]
    }
}
 

Request   

GET api/v1/order-limits

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

Query Parameters

partner_user_id   string   

ID користувача від мерчанта (унікальний ідентифікатор вашого клієнта). Example: customer_123

amount   number  optional  

Сума платежу для перевірки (опціонально). Example: 500

Body Parameters

amount   number  optional  

Must be at least 0. Example: 27

partner_user_id   string   

Must not be greater than 255 characters. Example: n

Response

Response Fields

success   boolean   

Ознака успішного запиту.

data   object   
can_create_payment   boolean   

Чи можна створити платіж.

limits   object   

Актуальні ліміти та банки або null.

errors   string[]   

Бізнес-причини, через які платіж недоступний.

Створити платіж

requires authentication

Створює новий платіж з автоматичним вибором карти для переказу. Автоматично створює або оновлює користувача з переданими даними.

Принцип роботи

  1. Створення/оновлення користувача - Якщо користувач не існує, він буде створений з переданими метаданими
  2. Валідація даних - Перевірка суми, банку та інших параметрів
  3. Автоматичний вибір карти - Система автоматично вибирає найкращу карту для переказу
  4. Створення замовлення - Формується замовлення з інструкціями для клієнта
  5. Повернення даних - Отримуєте всю необхідну інформацію для показу клієнту

Приклад використання (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"
}
 

Request   

POST api/v1/order

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

amount   number   

Сума платежу (від 50 до 10000 UAH). Example: 500

bank   string  optional  

ID банку для переказу. Якщо не вказано, користувач вибере банк за посиланням фіксованої суми. Example: monobank

partner_user_id   string   

ID користувача від мерчанта (унікальний ідентифікатор вашого клієнта). Example: customer_123

merchant_payment_id   string  optional  

Унікальний ID замовлення від мерчанта (якщо не вказати, згенерується автоматично). Example: ORDER_123456

description   string  optional  

Опис платежу (відображається клієнту). Example: Оплата за замовлення #123456

redirect_url   string  optional  

URL повернення після завершення платежу. Must be a valid URL. Must not be greater than 255 characters. Example: https://merchant.example/orders/ORDER_123456

metadata   object  optional  

Додаткові дані користувача для створення/оновлення профілю.

name   string  optional  

Ім'я користувача. Example: Іван Петров

email   string  optional  

Email користувача. Example: [email protected]

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"
}
 

Request   

POST api/v1/receipt/verify

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: multipart/form-data

Accept      

Example: application/json

Body Parameters

file   file   

Файл квитанції (pdf/jpg/png). Example: /tmp/phpzo49xU

mode   string   

verify | match. Example: verify

currency   string  optional  

Валюта квитанції, якщо відома. Must not be greater than 10 characters. Example: UAH

expected   object  optional  

Очікувані значення для режиму match.

amount   number  optional  

Очікувана сума. Example: 4326.41688

date   string  optional  

Очікувана дата. Example: architecto

card_number   string  optional  

Очікувана картка. Example: architecto

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"
}
 

Request   

GET api/v1/merchant/settings

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

Response

Response Fields

success   boolean   

Ознака успішного запиту.

data   object   
allowed_banks   object   

Актуальні коди та назви банків.

pricing   object   

Поточні тарифи мерчанта в USD.

topup_verification_fee   number   

Ціна успішного поповнення.

payout_fee_percentage   number   

Відсоток тарифу виплати.

Отримати суму доступних платежів для мерчанта

requires authentication

Повертає загальну суму доступних коштів для прийому платежів з урахуванням зайнятих виплат та групових налаштувань мерчанта.

Інформація що повертається

Використання

Цей 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"
}
 

Request   

GET api/v1/merchant/available-payment-amounts

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

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));

Request   

GET api/v1/webhooks/info

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

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));

Request   

GET api/v1/webhooks/examples/payment

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

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));

Request   

GET api/v1/webhooks/examples/payout

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

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));

Request   

GET api/v1/webhooks/integration-flow

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

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));

Request   

GET api/v1/webhooks/signature-verification

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

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"
    }
}
 

Request   

POST api/v1/webhooks/test

Headers

X-API-Key      

Example: your-api-key-here

Content-Type      

Example: application/json

Accept      

Example: application/json

Body Parameters

data_type   string   

Тип даних: order або payout. Example: order

event_type   string   

Подія, сумісна з data_type. Example: order.paid

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"
}
 

Request   

GET api/currencies/{currencyCode}/banks

Headers

Content-Type      

Example: application/json

Accept      

Example: application/json

URL Parameters

currencyCode   string   

Трилітерний код валюти. Example: UAH

Response

Response Fields

success   boolean   

Ознака успішного запиту.

data   object   

Об'єкт код банку → назва банку.