Взаимодействие с сервисом
Сервис «Расчёты по номинальному счёту» делится на два блока:
- JSONRPC API
- Загрузка документов
Техническое описание методов публикуется в разделе «Методы».
Доступы
Чтобы площадка могла делать запросы к сервису «Расчёты по номинальному счёту», нужно запросить доступы.
Для получения доступов предоставьте информацию, с каких IP‑адресов могут приходить запросы в сторону банка .
Пример запроса доступа
Прошу предоставить доступ к песочнице и тестовому серверу.
Доступ до API точки сервиса «Расчёты по номинальному счёту» c ip-адреса: XXX.XXX.XXX.XXX
Проверка доступа
<address> — адрес соответствующего слоя (см. Адреса слоёв)
<system> — идентификатор площадки, который формируется при регистрации площадки в системе, запрашивается у Точка Банка
curl -vvv <address>/v2/jsonrpc -d '{
"jsonrpc": "2.0",
"method": "echo",
"params": {"text": "Hello world!!!"},
"id": "908ca508-f1f1-4256-9c43-9ba7ad9c45fb"
}' -H 'Content-Type: application/json' -H 'sign-system: <system>' -H 'sign-data: 12345' -H 'sign-thumbprint: 12345'
Адреса слоёв
Добавочная часть URL:
- Для JSONRPC API методов —
/v2/jsonrpc - для загрузки документов по бенефициару —
/upload_document/beneficiary - Для загрузки документов по сделке —
/upload_document/deal
| Слой | Адрес до API | Описание |
|---|---|---|
| Тестовый слой | https://pre.tochka.com/api/v1/cyclops | Для основного тестирования и проверки интеграции, на нём нужно проверять работу методов |
| Продакшен | https://api.tochka.com/api/v1/cyclops | Для работы с реальными пользователями |
Сертификаты
Для проверки корректности подписания запросов от площадки нужно предоставить публичный (открытый) ключ и сопроводительные документы, включая акт приёма‑передачи открытого ключа.
В API доступно два варианта подписания:
- КриптоПро CSP и ключ ГОСТ‑2012
- OpenSSL и RSA‑ключ
Для тестового слоя можно сформировать самоподписанный ключ (ГОСТ или RSA). Ключ тестового слоя не должен совпадать с ключом рабочего слоя.
Для рабочего слоя:
- При подписании через КриптоПро ключ должен соответствовать формату ГОСТ Р 34.10‑2012 и быть выпущен удостоверяющим центром (https://digital.gov.ru/ru/activity/govservices/certification_authority/).
- При подписании через OpenSSL ключ должен соответствовать формату RSA и содержать данные юрлица или ИП, которые представляют площадку (в ключе должен быть электронный адрес компании и её наименование или ФИО ИП). Срок действия RSA‑ключа — от 365 до 1825 дней (не более 5 лет).
Эмуляция платежей на тестовых слоях
При тестировании ключевым этапом является идентификация платежей. Чтобы на тестовом слое появились платежи, используется сервис «Tender‑helpers».
Чтобы эмулировать пополнение, нужно узнать у поддержки номер счёта, присвоенный вашей площадке для тестовых слоёв.
Общая информация
Сетевые правила для взаимодействия с сервисом
| Rule | Direction | Source | Destination | Protocol | Port(s) | Action | Description |
|---|---|---|---|---|---|---|---|
| 1 | INBOUND | 23.105.228.128/25 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 23.105.228.128/25 to local servers |
| 2 | INBOUND | 23.111.125.0/26 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 23.111.125.0/26 to local servers |
| 3 | INBOUND | 23.111.125.64/26 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 23.111.125.64/26 to local servers |
| 4 | INBOUND | 23.111.197.128/25 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 23.111.197.128/25 to local servers |
| 5 | INBOUND | 23.111.220.0/26 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 23.111.220.0/26 to local servers |
| 6 | INBOUND | 23.111.220.64/26 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 23.111.220.64/26 to local servers |
| 7 | INBOUND | 23.111.197.3/32 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 23.111.197.3/32 to local servers |
| 8 | INBOUND | 23.111.197.4/32 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 23.111.197.4/32 to local servers |
| 9 | INBOUND | 23.105.228.3/32 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 23.105.228.3/32 to local servers |
| 10 | INBOUND | 23.105.228.4/32 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 23.105.228.4/32 to local servers |
| 11 | INBOUND | 91.193.217.3/32 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 91.193.217.3/32 to local servers |
| 12 | INBOUND | 91.193.217.4/32 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 91.193.217.4/32 to local servers |
| 13 | INBOUND | 185.169.155.210/32 | Local Servers Subnet | TCP | Any | ALLOW | Allow inbound traffic from external subnet 185.169.155.210/32 to local servers |
| 14 | OUTBOUND | Local Servers Subnet | 23.105.228.128/25 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 23.105.228.128/25 |
| 15 | OUTBOUND | Local Servers Subnet | 23.111.125.0/26 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 23.111.125.0/26 |
| 16 | OUTBOUND | Local Servers Subnet | 23.111.125.64/26 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 23.111.125.64/26 |
| 17 | OUTBOUND | Local Servers Subnet | 23.111.197.128/25 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 23.111.197.128/25 |
| 18 | OUTBOUND | Local Servers Subnet | 23.111.220.0/26 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 23.111.220.0/26 |
| 19 | OUTBOUND | Local Servers Subnet | 23.111.220.64/26 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 23.111.220.64/26 |
| 20 | OUTBOUND | Local Servers Subnet | 23.111.197.3/32 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 23.111.197.3/32 |
| 21 | OUTBOUND | Local Servers Subnet | 23.111.197.4/32 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 23.111.197.4/32 |
| 22 | OUTBOUND | Local Servers Subnet | 23.105.228.3/32 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 23.105.228.3/32 |
| 23 | OUTBOUND | Local Servers Subnet | 23.105.228.4/32 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 23.105.228.4/32 |
| 24 | OUTBOUND | Local Servers Subnet | 91.193.217.3/32 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 91.193.217.3/32 |
| 25 | OUTBOUND | Local Servers Subnet | 91.193.217.4/32 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 91.193.217.4/32 |
| 26 | OUTBOUND | Local Servers Subnet | 185.169.155.210/32 | TCP | Any | ALLOW | Allow outbound traffic from local servers to external subnet 185.169.155.210/32 |
Требования к запросам
Все входящие запросы должны быть в кодировке UTF‑8 и содержать заголовки:
Content-Type— описание данных, содержащихся в теле запросаsign-data— подпись тела запросаsign-thumbprint— отпечаток подписиsign-system— идентификатор площадки
Если не будут переданы перечисленные заголовки, вернётся ошибка 400. Если будет проблема при проверке подписи — ошибка 403.
Content-Type
Для обращения к JSONRPC-методам Content-Type должен быть application/json.
Для загрузки документов Content-Type должен быть одним из значений:
- application/pdf
- image/gif
- image/jpeg
- image/pjpeg
- image/png
- image/tiff
- image/x-tiff
- image/bmp
- image/x-windows-bmp
- image/x-ms-bmp
- image/ms-bmp
- image/x-bmp
sign-system
Идентификатор площадки. Выдаётся при создании площадки на соответствующем слое и обычно одинаков для всех слоёв.
sign-thumbprint
Отпечаток подписи. Нужен, чтобы понять, каким ключом была выполнена подпись. У площадки может быть несколько подписей.
sign-data
Чтобы банк мог убедиться, что запрос пришёл от площадки, все запросы подписываются электронной подписью.
Подробности — в разделах Подписание запросов (КриптоПро) и Подписание запросов (RSA).
Подписание запросов
Подписание запросов (КриптоПро)
Процесс подписания
Все отправляемые запросы должны быть подписаны закрытым ключом, и подпись должна находиться в заголовке запроса.
Алгоритм подписания:
- Скопируйте полностью тело запроса
- Посчитайте
sha256от тела - Подпишите документ через КриптоПро
- Добавьте подпись в заголовок
sign-data - Добавьте заголовок
sign-systemс идентификатором площадки - Добавьте заголовок
sign-thumbprintс отпечатком ключа, которым выполнялось подписание
Пример процесса подписания
Сформированный запрос:
{
"account": "40702810914270002130",
"amount": "63.25",
"bik": "044525999",
"inn": "5902996879",
"kpp": "590201001",
"name": "Общество с ограниченной ответственностью \"Бэнтэн Эксперт\"",
"payment_destination": "Пополнение виртуального счёта без НДС",
"transaction_date": "2020-01-24 07:46:49.989000+00:00",
"transaction_uid": "00c2b237-0386-455f-8b1d-4da8450feb4d",
"uuid": "e4585dc3-db7c-41e6-a28d-97fd937eb174"
}
Для тела сообщения вычисляем sha256:
fe19d0850415b900a1a704e496e29c4005d59fed64eca3597b9a2e026bc8996e
SHA256‑строку сохраняем в файл (без перевода строки) и подписываем через КриптоПро. Подпись нужно формировать с флагами:
-nocert— не добавлять сертификат отправителя-detached— формирование откреплённой подписи
cryptcp -sign ./request_sha256 ./request_sha256.sgn -detached -nocert -nochain -thumbprint '7a1831578b77f66d9bde6b4ea3a9763fa1aa733d'
Полученную подпись прикрепляем в заголовок sign-data. Обратите внимание, подпись будет с переносами строки, а для HTTP‑запроса переносы в заголовке критичны — удалите их.
Отправляем запрос.
Создание тестовой подписи
Для тестового слоя можно использовать самоподписанный сертификат.
csptestf -keyset -newkeyset -makecert -cont '\\.\HDIMAGE\test' -keytype exchange -exportable
Установка самоподписанного сертификата:
certmgr -inst -store uMy -cont '\\.\HDIMAGE\'
Получение публичного ключа из приватного:
certmgr -export -store uMy -cert -dest certificate.der
Подписание запросов (RSA)
Процесс подписания
Все отправляемые запросы должны быть подписаны закрытым ключом, и подпись должна находиться в заголовке запроса.
Алгоритм подписания:
- Скопируйте полностью тело запроса.
- Подпишите документ через OpenSSL с
sha256. - Добавьте подпись в заголовок
sign-data. - Добавьте заголовок
sign-systemс идентификатором площадки. - Добавьте заголовок
sign-thumbprintс отпечатком ключа.
Пример процесса подписания
Сформированный запрос:
{
"account": "40702810914270002130",
"amount": "63.25",
"bik": "044525999",
"inn": "5902996879",
"kpp": "590201001",
"name": "Общество с ограниченной ответственностью \"Бэнтэн Эксперт\"",
"payment_destination": "Пополнение виртуального счёта без НДС",
"transaction_date": "2020-01-24 07:46:49.989000+00:00",
"transaction_uid": "00c2b237-0386-455f-8b1d-4da8450feb4d",
"uuid": "e4585dc3-db7c-41e6-a28d-97fd937eb174"
}
Подписываем сообщение:
openssl dgst -sha256 -sign <private_file_path> -out <output_sign_file_path> <message_file_path>
private_file_path— путь до приватного ключаoutput_sign_file_path— путь, куда сохранить результат подписиmessage_file_path— путь до подписываемого сообщения
Файл output_sign_file_path преобразуем в base64:
base64 <sign_file_path> > <output_sign_base64_file_path>
sign_file_path— путь до подписиoutput_sign_base64_file_path— путь, куда сохранить результат подписи в base64
Полученный результат прикрепляем в заголовок sign-data. Обратите внимание: подпись будет с переносами строки, а для HTTP‑запроса переносы в заголовке критичны — удалите переносы строки.
Если нужно декодировать base64:
base64 -d <base64_file_path> > <output_file_path>
base64_file_path— файл в base64output_file_path— путь, куда сохранить результат
Проверка сообщения (не требуется в работе с сервисом)
openssl dgst -sha256 -verify <(openssl x509 -in <cert_file_path> -pubkey -noout) -signature <sign_data_file_path> <message_file_path>
cert_file_path— путь до сертификатаsign_data_file_path— путь до подписиmessage_file_path— путь до сообщения
Создание приватного ключа
Для каждого слоя нужно генерировать отдельный приватный ключ и сертификат. Приватную часть никому нельзя передавать.
openssl genrsa -out rsaprivkey.pem 2048
Создание публичного ключа
Формирование публичного сертификата на основе приватного ключа (атрибут -days 1825 задаёт срок действия в днях). Его нужно передать сотрудникам банка.
openssl req-new-x509 \
-key rsaprivkey.pem \
-days 1825 \
-out rsaacert.pem \
-subj "/C=RU/ST=Moscow/L=Moscow/O=MyCompany/OU=API/CN=cyclops/emailAddress=support@mycompany.ru"
Извлечение публичной части сертификата:
openssl x509 -in rsaacert.pem -text -noout
Сертификат будет выглядеть так:
-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIUOMamoGWXd5FATOQzf74j2tP6tWAwDQYJKoZIhvcNAQEL
...
-----END CERTIFICATE-----
Получение thumbprint (SHA1 отпечатка) в читаемом виде:
noout openssl x509 -in rsaacert.pem -noout -fingerprint -sha1
Пример:
SHA1 Fingerprint=BC:33:8B:6A:5D:E8:15:8E:A0:3A:22:35:06:33:A3:A1:15:F3:90:34
Получение thumbprint (SHA1 отпечатка) в формате для заголовка sign-thumbprint:
openssl x509 -in rsaacert.pem -noout -fingerprint -sha1 \
| sed 's/.*=//' | tr -d ':' | tr 'A-Z' 'a-z' > THUMBPRINT
Пример результата:
bc338b6a5de8158ea03a22350633a3a115f39034
Формирование отправляемого сообщения (сохраняем тело запроса в файл message):
echo -n '{"id": "0d6a26ea-84f0-4be2-9999-b46edc9b59b6", "jsonrpc": "2.0", "method": "list_payments", "params": {"filters": {"identify": false}}}' > message
Проверка, что нет перевода строки:
cat -A message
В конце не должно быть $.
Подписание сообщения (sha256). Это создаст бинарный файл message.sgn, содержащий подпись.
openssl dgst -sha256 -sign rsaprivkey.pem -out message.sgn message
Подпись преобразуем в base64:
base64 -i message.sgn | tr -d '\n' > BASE64_SIGNATURE
В заголовке подпись должна быть одной строкой без переносов.
Запрос в Расчёты по номинальному счёту (без переносов в sign-data):
curl -X POST "https://pre.tochka.com/api/v1/cyclops/v2/jsonrpc" \
-H "sign-data: <BASE64_SIGNATURE>" \
-H "sign-thumbprint: <THUMBPRINT>" \
-H "sign-system: abc" \
-H "Content-Type: application/json" \
--data-binary @message
Пример скрипта на PHP
<?php
if ($argc < 3) {
die("Usage: php script.php <headers_json> <data_json>\n");
}
$headers = json_decode($argv[1], true); // Заголовки в формате JSON
$datas = json_decode($argv[2], true); // Данные в формате JSON
function fetch($headers, $datas) {
// Загружаем приватный ключ
$privateKey = file_get_contents('/path/to/your/rsaprivkey.pem');
$privateKeyResource = openssl_pkey_get_private($privateKey);
if ($privateKeyResource === false) {
throw new Exception('Invalid private key provided.');
}
// Сериализуем данные в JSON
if (!is_string($datas)) {
$datas = json_encode($datas);
}
// Подписываем данные
openssl_sign($datas, $signature, $privateKeyResource, OPENSSL_ALGO_SHA256);
// Конвертируем подпись в base64
$base64Signature = base64_encode($signature);
// Удаляем переносы строк
$signData = str_replace(array("\r", "\n"), '', $base64Signature);
// Инициализируем cURL
$ch = curl_init();
// Устанавливаем параметры cURL
curl_setopt_array($ch, [
CURLOPT_URL => "<подставьте хост Cyclops – разный для каждого слоя>",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 60,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_POSTFIELDS => $datas,
CURLOPT_HTTPHEADER => array_merge($headers, [
"sign-data: $signData",
"sign-thumbprint: <подставьте отпечаток>",
"sign-system: <подставьте наименование площадки>"
])
]);
// Выполняем запрос
$response = curl_exec($ch);
// Получаем код ошибки
$curlErrno = curl_errno($ch);
// Закрываем cURL
curl_close($ch);
// Возвращаем результат
return [
"connection_validation" => $curlErrno,
"response" => json_decode($response, true)
];
}
// Выполнение функции fetch с параметрами
$result = fetch($headers, $datas);
print_r($result);
Пример использования скрипта:
php script.php '{"Content-Type": "application/json"}' '{
"id": "c5f84fc9-bc90-4b35-94b6-880cc9124e0a",
"jsonrpc": "2.0",
"method": "create_beneficiary_fl",
"params": {
"inn": "908867998158",
"beneficiary_data": {
"first_name": "Иванов",
"middle_name": "Иван",
"last_name": "Иванович",
"birth_date": "2024-02-29",
"birth_place": "Москва",
"passport_series": "4412",
"passport_number": "555555",
"passport_date": "2024-02-29",
"registration_address": "683031, г. Петропавловск-Камчатский, пр-кт. Карла Маркса, д. 21/1, офис 305",
"resident": true
}
}
}'
Важные подсказки, если проверка подписи не проходит:
- Проблемы с кириллицей и кодировками. Убедитесь, что все строки и данные закодированы в UTF‑8.
- Локальная проверка. Пройдите все шаги по созданию и проверке подписей локально (OpenSSL), чтобы отладить проблемы до отправки запросов.
- Пошаговая отладка с cURL. Если подпись не проходит, попробуйте отправлять запросы вручную через cURL, используя команды из документации.
Работа с интернет-эквайрингом
Чтобы подключить интернет-эквайринг Точка Банка, напишите на почту public-api@tochka.com.
Документация:
Генерация ссылок на оплату происходит при помощи метода Create Payment Operation из API банка. Это отдельный сервис, поэтому потребуется дополнительная интеграция.
Помимо метода для генерации платёжных ссылок необходимо реализовать следующие методы:
- Get Payment Pperation Info — получение статуса транзакции
- Refund Payment Operation — возврат средств покупателю
- Get Payment Registry — метод для получения реестра платежей по интернет-эквайрингу
Особенности работы интернет-эквайринга и номинального счёта:
- Пополнение номинального счёта по СБП рекомендуем реализовать через метод Создать QR-код для C2B пополнения. Но если вы решили использовать API банка для пополнения номинального счёта через СБП, то для возврата средств необходимо использовать метод Вернуть платёж.
Любые другие методы возврата средств, поступивших по СБП, могут привести к расхождению балансов виртуальных счетов. - Платежи по интернет-эквайрингу зачисляются на номинальный счёт не сразу, а вначале следующего дня одним платежом, который будет равен сумме платежей за предыдущий день.
Например, 1 января было 6 платежей по 100 рублей, тогда 2 января ночью будет зачислен платеж на сумму 600 рублей за вычетом комиссии эквайринга с идентификаторомacquiring-***и назначением платежа«Зачисление денежных средств по договору об обслуживании держателей платежных карт по терминалу TID ******** за дд.мм.гггг. Сумма комиссии **.**. НДС не предусмотрен». - Схему возврата платежей и корректировки балансов виртуальных счетов бенефициаров вы можете найти здесь.