Перед использованием API необходимо выполнить настройку:
uuid, public_key, private_keyprivate_key, public_key показываются один раз - сохраните сразу!ID платформы - идентификатор платформы для разделения трафикаuuid (kid) - идентификатор API‑ключаpublic_key - публичная часть ключаprivate_key - секрет для подписи запросов (хранить конфиденциально!)Все запросы (кроме получения токена) требуют JWT аутентификации:
Authorization: JWT <token>
Подробнее см. эндпоинт /session/jwt/ в разделе "Authentication".
Сервис отправляет callback на ваш URL при изменении статуса:
Callback отправляется HTTP POST с JSON телом.
Сервис добавляет HTTP‑заголовок:
X-Token-Sign: <signature_base64>
X-Token-Sign — это base64 от байтов подписи.Подписываемая строка строится так:
REQUEST_METHOD + "\n" + BODY_RAW
Где:
REQUEST_METHOD — HTTP‑метод (например, POST)BODY_RAW — сырой текст тела запросаТребования:
pyOpenSSL==23.2.0Важно:
raw_body должен быть bytes, полученный от веб‑фреймворка (например, request.body), без любых изменений.method должен быть тем, что пришло в запросе (POST).METHOD + "\n" + raw_body.decode("utf-8") (перенос строки — \n).import base64
from OpenSSL import crypto
# PEM строка публичного ключа сервиса
PUBLIC_KEY_PEM = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvocGJQ8SeTO7sWe6Qkyd
7aeLC/PBKhvzZOhm6U7h6IzY2xHDQHbu6fvEqVqmLZML7LXmLUmcBXptD7ENSXzi
en0oweQXVQJNi6CRGFZNXlmiimG7xoUu77tLyAyP8RxZnEKOHOADO0Vom6tsVYdE
vQfz66so6e2IRTKWW8OXgpx4WW14MjepShxMYpP9t+WMYnG3y/+nzb8Y53u3ZO07
hFfveOIAtoXVPZvDUnFd+iJHZSePhnxlf2tiln2rOPVth5vpezMISbQJRqPgmHk/
jN4hPsJkIn+OuM/med4xaUA50Uqg+7cYeDVIcQfm/IoIhyq/uGn+zUi46MrrF44I
PQIDAQAB
-----END PUBLIC KEY-----"""
def verify_callback_signature(method: str, raw_body: bytes, x_token_sign: str) -> bool:
message = method.upper() + "\n" + raw_body.decode("utf-8")
signature = base64.b64decode(x_token_sign)
pub_key = crypto.load_publickey(crypto.FILETYPE_PEM, PUBLIC_KEY_PEM)
cert = crypto.X509()
cert.set_pubkey(pub_key)
try:
crypto.verify(cert, signature, message.encode("utf-8"), "sha256")
return True
except Exception:
return False
Публичный ключ для проверки подписи:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvocGJQ8SeTO7sWe6Qkyd
7aeLC/PBKhvzZOhm6U7h6IzY2xHDQHbu6fvEqVqmLZML7LXmLUmcBXptD7ENSXzi
en0oweQXVQJNi6CRGFZNXlmiimG7xoUu77tLyAyP8RxZnEKOHOADO0Vom6tsVYdE
vQfz66so6e2IRTKWW8OXgpx4WW14MjepShxMYpP9t+WMYnG3y/+nzb8Y53u3ZO07
hFfveOIAtoXVPZvDUnFd+iJHZSePhnxlf2tiln2rOPVth5vpezMISbQJRqPgmHk/
jN4hPsJkIn+OuM/med4xaUA50Uqg+7cYeDVIcQfm/IoIhyq/uGn+zUi46MrrF44I
PQIDAQAB
-----END PUBLIC KEY-----
Callback отправляется с повторами при ошибках:
Успешной доставкой считается:
Статус находится в payment.status:
| Значение | Смысл |
|---|---|
created |
Создана |
in_progress |
В работе |
success |
Выполнена |
success_incorrect_amount |
Выполнена с неверной суммой |
cancelled |
Отменена/истекла |
failed |
Не удалось обработать |
{
"payment": {
"id": "13a840e4-f078-4efc-9372-008ac038dee3",
"external_id": "my-pay-in-id-001",
"total": "20.60",
"fee": "0.60",
"fee_native": "60.00",
"amount": "20.00",
"amount_native": "2000.00",
"received_amount": "10.00",
"received_amount_native": "1000.00",
"rate": "100",
"redirect_url": "https://example.com/redirect",
"paymethod": 3547,
"paymethod_description": "Сбербанк",
"date_created": 1697798134,
"timeout": 900,
"status": "success_incorrect_amount",
"card": "4111111111100031",
"name": "Иванов И.",
"cancel_message": null
},
"platform": {
"name": "client",
"id": "127ea230-ab27-4941-bf1f-8fd2ceaf92d1"
}
}
Примечания:
external_id — это ваш id, который вы передавали при создании.Статус находится в payment.status:
| Значение | Смысл |
|---|---|
created |
Создана |
in_progress |
В обработке |
confirmed |
Выполнена |
cancelled |
Отменена |
failed |
Ошибка |
{
"payment": {
"id": 1,
"external_id": "Your Payment #100",
"amount": "100",
"amount_native": "10000",
"rate": "100",
"fee": "1",
"fee_native": "100",
"total": "101",
"date_created": 1697809937,
"date_closed": 0,
"sbp": false,
"status": "confirmed",
"details": "1111111111111111",
"comment": "Комментарий",
"cancel_comment": null,
"cheque": {
"content": null,
"ext": null
},
"paymethod": 3547,
"paymethod_description": "Сбербанк"
}
}
Примечания:
sbp=true, дополнительно придут bank и bank_name (а paymethod может отсутствовать).Эндпоинт для получения JWT токена на основе подписанного JWT request.
Проекты NetPay используют JWT авторизацию (см. jwt.io и RFC 7519).
Authorization: JWT <token>
Важно: не нужно получать новый token на каждый запрос. Получайте новый token только при истечении срока действия или при отзыве/перевыпуске ключей.
Есть два разных TTL:
exp вы задаёте сами. Делайте его коротким (например, 5–60 минут)jti (обязательно): уникальный идентификатор запроса (случайное значение достаточной длины, минимум 12 байт)exp (рекомендуется): время истечения JWT request в формате Unix time (секунды)kid — это UID/uuid API-ключаjti слишком короткий или не уникальный (нужна достаточная энтропия, например 12+ байт)| kid required | string UID/идентификатор API-ключа |
| jwt_token required | string Подписанный JWT request (алгоритм RS256) |
| token | string JWT access token для использования в последующих запросах |
{- "kid": "550e8400-e29b-41d4-a716-446655440000",
- "jwt_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MDc5MDk2MDAsImp0aSI6ImFiY2RlZjEyMzQ1Njc4OTAifQ.signature"
}{- "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}Эндпоинт для получения информации о балансе аккаунта пользователя.
Параметры запроса отсутствуют — эндпоинт возвращает информацию о балансе текущего пользователя, определённого по JWT токену.
Права доступа: API ключу достаточно иметь права read-only
balance)| Поле | Тип | Описание |
|---|---|---|
balance |
string (decimal) | Общий баланс пользователя в USDT (с учётом замороженных средств). Формат: "{:.2f}" (2 знака после запятой) |
available |
string (decimal) | Доступный баланс (общий минус замороженный): balance - frozen. Формат: "{:.2f}" |
frozen |
string (decimal) | Замороженные средства (средства, зарезервированные для активных платежей/выплат). Формат: "{:.2f}" |
wallets)Объект, где ключ — код валюты (например, "RUB", "USD"), а значение — объект с информацией о кошельке:
| Поле | Тип | Описание |
|---|---|---|
currency |
string | Код валюты кошелька (например, "RUB", "USD") |
uuid |
string (UUID) | Уникальный идентификатор кошелька |
balance |
string (decimal) | Общий баланс кошелька в указанной валюте (с учётом замороженных средств). Формат: "{:.2f}" |
available |
string (decimal) | Доступный баланс кошелька: balance - frozen. Формат: "{:.2f}" |
frozen |
string (decimal) | Замороженные средства на кошельке. Формат: "{:.2f}" |
Примечание: Если у пользователя нет кошельков в других валютах, объект wallets будет пустым {}.
balance на верхнем уровне относится к основному балансу пользователя в USDTfrozen показывает средства, зарезервированные для активных операций (например, созданные, но ещё не обработанные выплаты)wallets будет пустым {}| username | string |
string <email> | |
object Основной баланс в USDT | |
object Кошельки в различных валютах |
import requests host = "{HOST, уточнить у поддержки}" token = "{JWT токен}" response = requests.get( f"https://{host}/api/papi/accounts/get/", headers={ "Authorization": f"JWT {token}", "Content-Type": "application/json" } ) if response.status_code == 200: data = response.json() print(f"Username: {data['username']}") print(f"Balance (USDT): {data['balance']['balance']}") print(f"Available: {data['balance']['available']}") for currency, wallet in data['wallets'].items(): print(f"\nWallet {currency}:") print(f" Balance: {wallet['balance']}") print(f" Available: {wallet['available']}")
{- "username": "merchant_username",
- "balance": {
- "balance": "1000.00",
- "available": "950.00",
- "frozen": "50.00"
}, - "wallets": {
- "RUB": {
- "currency": "RUB",
- "uuid": "550e8400-e29b-41d4-a716-446655440000",
- "balance": "50000.00",
- "available": "48000.00",
- "frozen": "2000.00"
}, - "USD": {
- "currency": "USD",
- "uuid": "660e8400-e29b-41d4-a716-446655440001",
- "balance": "1000.00",
- "available": "1000.00",
- "frozen": "0.00"
}
}
}Входящие платежи
Callbacks: При изменении статуса платежа сервер отправляет webhook на указанный callback_url. См. документацию по верификации подписи в схеме CallbackPayIn.
Создание входящего платежа и получение реквизитов для оплаты.
| Поле | Тип | Описание |
|---|---|---|
platform |
string (UUID) | UUID платформы. Платформа должна принадлежать текущему пользователю и быть активной |
currency |
string | Код валюты (например, RUB). Рекомендуется передавать валюту, соответствующую выбранному paymethod |
client_id |
string | Идентификатор клиента в вашей системе |
paymethod |
integer | Код метода оплаты. Запрашивается в рабочем чате |
amount |
string/number (Decimal) | Сумма в "нативной" валюте зачисления. Обязательно, если usdt_amount не передан |
usdt_amount |
string/number (Decimal) | Сумма в USDT для пересчёта в нативную валюту. Обязательно, если amount не передан |
Важно: Нужно передать ровно одно из полей: amount или usdt_amount.
| Поле | Тип | Описание |
|---|---|---|
callback_url |
string (URL) | URL для коллбеков по платежу |
id |
string | Ваш внешний идентификатор платежа |
bank |
string | Наименование банка отправителя |
link - ссылка на виджет/страницу оплатыcard - реквизиты (вне зависимости от метода оплаты)wallet - реквизиты кошелька (если применимо)name - получатель платежаpaymethod_description - возвращается название банкаtimeout - время жизни заявки в секундахdate_created - Unix time (секунды)| platform required | string <uuid> UUID платформы |
| currency required | string Код валюты (например, RUB, USD) |
| client_id required | string Идентификатор клиента в вашей системе |
| paymethod required | integer Код метода оплаты (запрашивается в рабочем чате) |
| amount | string Сумма в нативной валюте (обязательно, если нет usdt_amount) |
| usdt_amount | string Сумма в USDT (обязательно, если нет amount) |
| callback_url | string <uri> URL для callback уведомлений |
| id | string Ваш внешний идентификатор платежа |
| ok | boolean |
| message | string |
object (PayInPayment) |
{- "platform": "e2488acf-4c5c-4859-b24a-35f09d9e105a",
- "currency": "RUB",
- "client_id": "client-123",
- "paymethod": 102120,
- "amount": "10000",
- "id": "my-payment-001"
}{- "ok": true,
- "message": "Универсальная обработка: выбран метод оплаты: 102120",
- "payment": {
- "total": "101.00",
- "fee": "1.00",
- "fee_native": "100.00",
- "rate": "100",
- "amount": "100.00",
- "amount_native": "10000.00",
- "received_amount": "0.00",
- "received_amount_native": "0.00",
- "country": "Россия",
- "currency": "RUB",
- "card": "1111 1111 1111 1111",
- "wallet": "",
- "name": "Иванов Иван Иванович",
- "operation_id": "12345",
- "id": "e2488acf-4c5c-4859-b24a-35f09d9e105a",
- "paymethod": 102120,
- "paymethod_description": "Название банка",
- "status": "in_progress",
- "date_created": 1697798134,
- "timeout": 900
}
}{- "payment": {
- "total": "101.00",
- "fee": "1.00",
- "fee_native": "100.00",
- "rate": "100",
- "amount": "100.00",
- "amount_native": "10000.00",
- "received_amount": "0.00",
- "received_amount_native": "0.00",
- "country": "Россия",
- "currency": "RUB",
- "card": "1111 1111 1111 1111",
- "wallet": "",
- "name": "Иванов Иван Иванович",
- "operation_id": "12345",
- "id": "e2488acf-4c5c-4859-b24a-35f09d9e105a",
- "paymethod": 102120,
- "paymethod_description": "Название банка",
- "status": "in_progress",
- "date_created": 1697798134,
- "timeout": 900,
- "external_id": "my-pay-in-id-001",
- "cancel_message": null
}, - "platform": {
- "name": "client",
- "id": "127ea230-ab27-4941-bf1f-8fd2ceaf92d1"
}
}Получение детальной информации о входящем платеже по его UUID.
Важно: метод ищет только по внутреннему UUID заявки (поле id в ответе при создании),
а НЕ по вашему внешнему external_id.
| Поле | Тип | Описание |
|---|---|---|
id |
string (UUID) | UUID заявки в нашей системе. Метод не ищет по вашему внешнему id |
| Значение | Смысл |
|---|---|
created |
Заявка создана, реквизиты ещё не получены / процессинг не завершён |
in_progress |
Заявка в работе (реквизиты выданы, ожидается оплата) |
success |
Заявка успешно завершена на верную сумму |
success_incorrect_amount |
Заявка завершена, но сумма поступления отличается от ожидаемой |
cancelled |
Заявка отменена/истекла |
failed |
Не удалось обработать заявку (ошибка процессинга) |
| id required | string <uuid> UUID заявки в системе NetPay |
| ok | boolean |
object | |
object |
{- "id": "e2488acf-4c5c-4859-b24a-35f09d9e105a"
}{- "ok": true,
- "payment": {
- "total": "101.00",
- "fee": "1.00",
- "fee_native": "100.00",
- "rate": "100",
- "amount": "100.00",
- "amount_native": "10000.00",
- "received_amount": "0.00",
- "received_amount_native": "0.00",
- "country": "Россия",
- "currency": "RUB",
- "card": "1111 1111 1111 1111",
- "wallet": "",
- "name": "Иванов Иван Иванович",
- "operation_id": "12345",
- "id": "e2488acf-4c5c-4859-b24a-35f09d9e105a",
- "paymethod": 102120,
- "paymethod_description": "Название банка",
- "status": "in_progress",
- "date_created": 1697798134,
- "timeout": 900,
- "external_id": "my-pay-in-id-001",
- "cancel_message": null
}, - "platform": {
- "name": "Casino",
- "id": "dbe7dd2e-7481-4ade-92c0-227ea5b758aa"
}
}Исходящие платежи (выплаты)
Callbacks: При изменении статуса выплаты сервер отправляет webhook на указанный callback_url. См. документацию по верификации подписи в схеме CallbackPayOut.
Создание исходящей выплаты на карту или через СБП.
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
platform |
string (UUID) | Да | UUID платформы/витрины. Платформа должна принадлежать пользователю и быть активной |
payment |
object | Да | Данные выплаты (см. ниже) |
payment| Поле | Тип | Описание |
|---|---|---|
details |
string | Реквизит для выплаты: номер карты или номер телефона для СБП. Допустимы только цифры, пробелы и + (другие символы вроде - приведут к ошибке Incorrect Details) |
amount |
string/number (Decimal) | Сумма выплаты (сервер конвертирует/округляет до 2 знаков) |
paymethod |
integer | Код метода оплаты |
bank |
integer | ID банка. Обязателен для СБП (Запрашивается в рабочем чате) |
| Поле | Тип | Описание |
|---|---|---|
callback_url |
string (URL) или null | URL для коллбеков |
comment |
string | Комментарий к выплате |
id |
string | Ваш внешний идентификатор выплаты |
details - допустимы только цифры, пробелы и + (символы - могут вызвать ошибку)bank (ID банка)| Значение | Смысл |
|---|---|
created |
Выплата создана (средства уже заморожены) |
in_progress |
Выплата в обработке |
confirmed |
Выплата выполнена успешно |
cancelled |
Выплата отменена |
failed |
Ошибка при обработке выплаты |
| platform required | string <uuid> UUID платформы |
required | object |
| ok | boolean |
| message | string |
object (PayOutPayment) |
{- "platform": "dbe7dd2e-7481-4ade-92c0-227ea5b758aa",
- "payment": {
- "details": "1111111111111111",
- "amount": "10000",
- "paymethod": 102120,
- "comment": "Payout #42",
- "id": "my-payout-42"
}
}{- "ok": true,
- "message": "Payment(s) successfully created.",
- "payment": {
- "id": 102345,
- "external_id": "my-payout-42",
- "amount": "100.00",
- "amount_native": "10000.00",
- "fee": "1.00",
- "fee_native": "100.00",
- "rate": "100",
- "total": "101.00",
- "date_created": 1697809937,
- "date_closed": 0,
- "sbp": false,
- "status": "created",
- "details": "1111111111111111",
- "comment": "Payout #42",
- "cancel_comment": null,
- "paymethod": 102120,
- "paymethod_description": "AnyBank RUB P2P",
- "bank": 123,
- "bank_name": "Сбербанк",
- "cheque": {
- "content": "string",
- "ext": "string"
}
}
}{- "payment": {
- "id": 102345,
- "external_id": "my-payout-42",
- "amount": "100.00",
- "amount_native": "10000.00",
- "fee": "1.00",
- "fee_native": "100.00",
- "rate": "100",
- "total": "101.00",
- "date_created": 1697809937,
- "date_closed": 0,
- "sbp": false,
- "status": "created",
- "details": "1111111111111111",
- "comment": "Payout #42",
- "cancel_comment": null,
- "paymethod": 102120,
- "paymethod_description": "AnyBank RUB P2P",
- "bank": 123,
- "bank_name": "Сбербанк",
- "cheque": {
- "content": "string",
- "ext": "string"
}
}
}Получение детальной информации о выплате.
Нужно передать одно из полей: id или external_id.
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
id |
integer/string (число) | Да* | Внутренний ID выплаты. Также допускается передать ваш внешний ID |
external_id |
string | Да* | Ваш внешний ID выплаты |
* Если id не передан — обязателен external_id, и наоборот.
| Значение | Смысл |
|---|---|
created |
Выплата создана (средства заморожены), ожидает обработки |
in_progress |
Выплата в обработке |
confirmed |
Выплата выполнена успешно |
cancelled |
Выплата отменена |
failed |
Ошибка при обработке выплаты |
Примечание: Если sbp=true, вместо paymethod/paymethod_description возвращаются поля bank и bank_name. Часть числовых полей может возвращаться как строки (Decimal).
| id | integer Внутренний ID выплаты |
| external_id | string Ваш внешний ID выплаты |
| ok | boolean |
object (PayOutPayment) |
{- "id": 120123
}{- "ok": true,
- "payment": {
- "id": 102345,
- "external_id": "my-payout-42",
- "amount": "100.00",
- "amount_native": "10000.00",
- "fee": "1.00",
- "fee_native": "100.00",
- "rate": "100",
- "total": "101.00",
- "date_created": 1697809937,
- "date_closed": 0,
- "sbp": false,
- "status": "created",
- "details": "1111111111111111",
- "comment": "Payout #42",
- "cancel_comment": null,
- "paymethod": 102120,
- "paymethod_description": "AnyBank RUB P2P",
- "bank": 123,
- "bank_name": "Сбербанк",
- "cheque": {
- "content": "string",
- "ext": "string"
}
}
}