Как принимать пополнения через P2P-переводы и делать выплаты
Вам нужно принимать пополнения через P2P-переводы (пользователь сам переводит деньги по реквизитам) и делать выплаты на карты или счета. Вы реализуете P2P-поток: Gateway создаёт заказ у провайдера, возвращает реквизиты для перевода, а затем отслеживает поступление средств.
Отличие от H2H: данные карты плательщика не передаются — Gateway только создаёт заказ и возвращает реквизиты, куда пользователь должен перевести деньги. Что вам понадобится: API-ключ провайдера, спецификация его эндпоинтов (pay, status, callback), тестовый счёт/карта для выплат.
1. Реализуйте пополнение (Payin) через P2P — получение реквизитов
Заголовок раздела «1. Реализуйте пополнение (Payin) через P2P — получение реквизитов»Шаг 1. Примите запрос на создание заказа
Заголовок раздела «Шаг 1. Примите запрос на создание заказа»Входящий запрос не содержит данных карты — только информация о пользователе:
{ "method_name": "pay", "params": { "customer": { "email": "user@example.com", "ip": "192.168.1.1" } }, "payment": { "token": "tok_xxxx", "gateway_amount": 10000, "gateway_currency": "USD" }, "settings": { "api_key": "provider_api_token" }}Полная структура запроса описана в Базовые Контракты.
Шаг 2. Создайте заказ у провайдера
Заголовок раздела «Шаг 2. Создайте заказ у провайдера»Отправьте запрос провайдеру с суммой, валютой и reference (токеном платежа). Провайдер создаст заказ и вернёт реквизиты для перевода.
Шаг 3. Верните реквизиты для перевода
Заголовок раздела «Шаг 3. Верните реквизиты для перевода»Ответ должен содержать status: "pending" и поле requisites:
{ "result": true, "status": "pending", "gateway_token": "order_12345", "amount": 10000, "currency": "USD", "requisites": { "card": "461761****3933", "holder": "IVAN I.", "bank_name": "BankOfBaku", "phone": "+77001234567" }, "logs": [...]}Поле requisites может содержать:
card— номер карты получателя (маскированный)holder— имя получателяbank_name— название банкаphone— номер телефона (для переводов на телефон)account— номер счётаlink— URL для перехода (SberPay и т.п.)deeplink— true, если реквизиты содержат ссылку для переходаqr_data— QR-код для перевода
Шаг 4. Реализуйте финализацию статуса
Заголовок раздела «Шаг 4. Реализуйте финализацию статуса»После того как пользователь перевёл деньги, провайдер присылает вебхук на POST /callback или статус проверяется через POST /status.
Реализация коллбеков описана в Callbacks & JWT. Проверка статуса — в Status и Payout.
2. Реализуйте выплату (Payout) через P2P
Заголовок раздела «2. Реализуйте выплату (Payout) через P2P»Шаг 1. Извлеките данные получателя
Заголовок раздела «Шаг 1. Извлеките данные получателя»{ "params": { "amount": 50000, "currency": "EUR", "customer": { "email": "receiver@example.com" }, "card": { "pan": "4111111111111111" } }, "payment": { "token": "payout_tok_xxxx" }, "settings": { "api_key": "provider_api_token" }}Важно: В P2P Payout сумма и валюта могут быть в
params, а не вpayment— проверьте спецификацию вашего провайдера.
Шаг 2. Конвертируйте сумму и отправьте выплату
Заголовок раздела «Шаг 2. Конвертируйте сумму и отправьте выплату»amount передаётся в копейках. Поделите на 100 перед отправкой провайдеру.
Шаг 3. Верните результат
Заголовок раздела «Шаг 3. Верните результат»{ "result": true, "status": "approved", "gateway_token": "payout_12345", "amount": 50000, "currency": "EUR", "details": "Payout successful", "logs": [...]}Если выплата не мгновенная — верните status: "pending" и ждите коллбек.
Чек-лист для реализации
Заголовок раздела «Чек-лист для реализации»Для пополнения (Payin)
Заголовок раздела «Для пополнения (Payin)»- Создать endpoint
POST /pay - Создать заказ у провайдера
- Получить реквизиты для перевода
- Вернуть
status: "pending"+requisites+gateway_token+logs - Реализовать
POST /callbackилиPOST /statusдля финализации статуса
Для выплаты (Payout)
Заголовок раздела «Для выплаты (Payout)»- Создать endpoint
POST /payout - Извлечь
params.card.panилиparams.bank_account - Сконвертировать
params.amount(в копейках) в основные единицы для провайдера - Отправить выплату провайдеру
- Вернуть
logsс деталями запроса/ответа - Если выплата не мгновенная — вернуть
status: "pending"и ожидать коллбек
Пример реализации на Node.js
Заголовок раздела «Пример реализации на Node.js»Пополнение (Payin)
Заголовок раздела «Пополнение (Payin)»app.post("/pay", async (req, res) => { const body = req.body; const amount = body.payment.gateway_amount / 100; const apiKey = body.settings.api_key;
const providerPayload = { amount, currency: body.payment.gateway_currency, reference: body.payment.token, };
const providerRes = await fetch("https://api.provider.com/v1/orders", { method: "POST", headers: { Authorization: `Bearer ${apiKey}` }, body: JSON.stringify(providerPayload), }); const data = await providerRes.json();
res.status(200).json({ result: true, status: "pending", gateway_token: data.id, amount: body.payment.gateway_amount, currency: body.payment.gateway_currency, requisites: { card: data.card_number, holder: data.beneficiary, bank_name: data.bank_name, }, logs: [ { request: { body: providerPayload }, status: providerRes.status, response: data, kind: "pay", duration: 0.5, }, ], });});Выплата (Payout)
Заголовок раздела «Выплата (Payout)»app.post("/payout", async (req, res) => { const body = req.body; const amount = body.params.amount / 100; const apiKey = body.settings.api_key;
const providerPayload = { amount, currency: body.params.currency, card: body.params.card?.pan, bank_account: body.params.bank_account, reference: body.payment.token, };
const providerRes = await fetch("https://api.provider.com/v1/payouts", { method: "POST", headers: { Authorization: `Bearer ${apiKey}` }, body: JSON.stringify(providerPayload), }); const data = await providerRes.json();
res.status(200).json({ result: true, status: data.status === "success" ? "approved" : "pending", gateway_token: data.id, amount: body.params.amount, currency: body.params.currency, logs: [ { request: { body: providerPayload }, status: providerRes.status, response: data, kind: "payout", duration: 0.5, }, ], });});