Перейти к содержимому

Как принимать платежи через редирект на страницу провайдера

Вам нужно принимать платежи без обработки карточных данных на вашей стороне — пользователь вводит данные карты напрямую на странице провайдера. Вы реализуете Redirect-поток: Gateway создаёт платёжную сессию у провайдера и возвращает URL для перенаправления.

Отличие от H2H: данные карты не передаются через Gateway — пользователь вводит их напрямую на странице провайдера. Что вам понадобится: API-ключ и публичный ключ провайдера, спецификация его эндпоинтов (pay, callback, status), тестовый аккаунт.


Входящий запрос содержит только информацию о пользователе и платеже:

{
"method_name": "pay",
"params": {
"customer": {
"email": "user@example.com",
"first_name": "Ivan",
"last_name": "Ivanov",
"country": "US",
"ip": "192.168.1.1"
}
},
"payment": {
"token": "tok_xxxx",
"gateway_amount": 10000,
"gateway_currency": "USD",
"product": "Premium Plan",
"order_number": "ORD-001"
},
"settings": {
"api_key": "provider_api_token",
"public_key": "provider_public_key",
"sandbox": false
},
"processing_url": "https://merchant.com/processing",
"callback_url": "https://merchant.com/callback"
}

Полная структура запроса описана в Базовые Контракты.

Отправьте провайдеру сумму, валюту, данные пользователя и URL для возврата (processing_url). Провайдер создаст платёжную страницу и вернёт URL для перенаправления.

{
"result": true,
"status": "pending",
"gateway_token": "session_12345",
"amount": 10000,
"currency": "USD",
"redirect_request": {
"url": "https://provider.com/payment_page",
"type": "get_with_processing",
"params": {}
},
"logs": [...]
}
Тип Описание
"get_with_processing" GET редирект + показать processing-страницу (используется чаще всего)
"post_iframes" POST в iframe
"get" Простой GET редирект
"post" Авто-отправка POST формы

Подробнее про формат redirect_request — в Базовые Контракты (секция 3).


2. Реализуйте обработку коллбека (POST /callback)

Заголовок раздела «2. Реализуйте обработку коллбека (POST /callback)»

После оплаты провайдер присылает webhook на POST /callback вашего Gateway:

  1. Валидируйте подпись провайдера (метод зависит от провайдера — JWT, RSA, HMAC)
  2. Нормализуйте статус (approved / declined)
  3. Отправьте результат в Business, подписав JWT ключом settings.sign_key

Полная инструкция по коллбекам и JWT — в Callbacks & JWT.


Для случаев, когда коллбек не пришёл, реализуйте эндпоинт проверки статуса:

{
"method_name": "status",
"payment": {
"token": "tok_xxxx",
"gateway_token": "session_12345"
},
"settings": {
"api_key": "provider_api_token"
}
}

Детальная спецификация — в Status и Payout.


  1. Создать endpoint POST /pay
  2. Извлечь payment.gateway_amount / 100, payment.token, settings
  3. Создать сессию у провайдера
  4. Получить URL платежной страницы от провайдера
  5. Вернуть status: "pending" + redirect_request с URL и типом
  6. Сформировать logs
  7. Реализовать POST /callback с валидацией подписи (см. Callbacks & JWT)
  8. Реализовать POST /status для проверки статуса (см. Status и Payout)

app.post('/pay', async (req, res) => {
const body = req.body;
const amount = body.payment.gateway_amount / 100;
const apiKey = body.settings.api_key;
// 1. Формируем запрос к провайдеру (без карты!)
const providerPayload = {
amount,
currency: body.payment.gateway_currency,
externalPaymentId: body.payment.token,
returnUrl: body.processing_url,
senderName: body.params?.customer?.first_name,
senderCountry: body.params?.customer?.country,
};
// 2. Отправляем запрос
const providerRes = await fetch('https://api.provider.com/v1/payments', {
method: 'POST',
headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
body: JSON.stringify(providerPayload),
});
const data = await providerRes.json();
// 3. Возвращаем redirect_request с URL платежной страницы
res.status(200).json({
result: true,
status: 'pending',
gateway_token: data.paymentId,
n amount: body.payment.gateway_amount,
currency: body.payment.gateway_currency,
redirect_request: {
url: data.redirectUrl,
type: 'get_with_processing',
params: {},
},
logs: [{
request: { body: providerPayload },
status: providerRes.status,
response: data,
kind: 'pay',
duration: 0.5,
}],
});
});