Skip to main content

FAQ — пополнения клиентам Т-Банка

Как сформировать цифровую подпись

  1. Извлеките и канонизируйте data — из исходного JSON-документа извлеките значение поля data как отдельный JSON-объект и приведите его к каноническому виду по стандарту RFC 8785.

    • Поля объекта отсортированы лексикографически — по имени ключа в UTF-8.
    • Нет пробелов, переносов и отступов — строка должна быть максимально компактной.
    • В одном объекте не должно быть повторяющихся ключей.
    • Кодировка — UTF-8.
    • Числовые поля должны быть конечными и представимыми в формате IEEE 754.
  2. Вычислите хеш от канонизированной строки data с использованием алгоритма ГОСТ Р 34.11-2012.

  3. Для полученного хеша вычислите значение подписи с использованием алгоритма ГОСТ Р 34.10-2012.

  4. Добавьте в исходный JSON блок crypto:

    • sign – электронная подпись, представленная в виде строки в формате Base64;
    • serial – серийный номер публичного сертификата, которым может быть проверена данная подпись;
    • algorithm – использованный при создании подписи криптоалгоритм.

Измененять структуру поля data и кодировку документа нельзя.

Поддерживаемые алгоритмы шифрования — передается в запросе в crypto.algorithm:

ЗначениеОписание
Crypto-pro 2012-256ГОСТ Р 34.11/34.10-2012 с длиной ключа 256 бит
Crypto-pro 2012-512ГОСТ Р 34.11/34.10-2012 с длиной ключа 512 бит

Пример реализации на Java
public class SignExample {

private static class SortingNodeFactory extends JsonNodeFactory {
@Override
public ObjectNode objectNode() {
return new ObjectNode(this, new TreeMap<>());
}
}

private static final SimpleModule BIG_NUMBER_SERIALIZER = new SimpleModule()
.addSerializer(BigInteger.class, new ToStringSerializer())
.addSerializer(BigDecimal.class, new ToStringSerializer());

private static final ObjectMapper MAPPER = JsonMapper.builder()
.nodeFactory(new SortingNodeFactory())
.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)
.addModule(new JavaTimeModule())
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.addModule(BIG_NUMBER_SERIALIZER)
.build();

@SneakyThrows
public static void main(String[] args) {
// инициализируем криптопро
final KeyStore keyStore = initCryptoPro();
// создаем POJO запроса
final PartnersRequest request = generatePartnersRequest();
// серилизуем в JSON блок data
final String dataJson = MAPPER.writeValueAsString(request.getData());
// получем подпись блока data (если алгоритм, например crypto-pro 2012-256)
final byte[] sign = makeSign_2012_256_handsome(keyStore, dataJson);
// получаем base64 строку
final String base64Sign = Base64.getEncoder().encodeToString(sign);
// заполняем поле подписи
request.getCrypto().setSign(base64Sign);
// получаем готовый JSON
final String json = MAPPER.writeValueAsString(request);
System.out.println(json);
}


@SneakyThrows
private static byte[] makeSign_2012_256_handsome(final KeyStore keyStore, final String strForSign) {
PrivateKey privateKey = (PrivateKey) keyStore.getKey(KEY_ALIAS, KEY_PASSWORD);

final MessageDigest digest = MessageDigest.getInstance(JCP.GOST_DIGEST_2012_256_NAME, JCP.PROVIDER_NAME);
final byte[] data = strForSign.getBytes(StandardCharsets.UTF_8);
byte[] signedData = digest.digest(data);

final Signature signature = Signature.getInstance(JCP.RAW_GOST_SIGN_2012_256_NAME);
signature.initSign(privateKey);
signature.update(signedData);

return signature.sign();
}
}

Обязательность полей

В методах Пополнения клиентам Т-Банка обязательными помечены только те поля, которые являются обязательными независимо от значения data.sourceCode.

Полный состав полей в запросе и ответе зависит от значения data.sourceCode и согласовывается индивидуально на этапе подключения к API.

Обязательные поля в запросе для data.amount > 15 000

Передавать следующие поля при data.amount <= 15 000 необязательно, но допустимо — логика не нарушится:

  • data.senderInfo.lastName
  • data.senderInfo.firstName
  • data.senderInfo.address

Обязательные поля в зависимости от data.sourceCode

Список полей не зависит от значения data.amount — эти поля должны передаваться во всех запросах.

Обязательные поля в запросе

data.senderInfo.extraInfo

Обязательные поля в ответе

  • mainData.additionalInfoPartners.identificationCheck
  • mainData.additionalInfoPartners.nameS
  • mainData.additionalInfoPartners.lastCardNumber
  • mainData.additionalInfoPartners.fullName
  • mainData.additionalInfoPartners.recHash

Возможные коды ответов

Успешные коды ответов

HTTP-статус Значение поля result Повторить запрос Значение поля comment Описание
2000НетЗапрос успешно обработан

Бизнес-ошибки

HTTP-статус Значение поля result Повторить запрос Значение поля comment
200141НетНеверный номер договора получателя.
200142НетНеверный номер карты получателя.
200143НетНеверный номер телефона получателя.
200144НетНевозможно однозначно определить получателя платежа, найдено более одного контакта с данным номером телефона.
200146НетНеверный номер телефона или переданный номер телефона не принадлежит оператору.
200149НетНеверный номер счета получателя.
200151НетСумма перевода меньше минимальной.
200152НетСумма перевода больше максимальной.
200153НетСумма пополнения после конвертации равна 0.
200159НетНевозможно идентифицировать клиента по переданным реквизитам пополнения.
200160НетОтсутствуют идентификационные данные при сумме пополнения больше 15 000 рублей.
200161НетДанная операция невозможна.
200162НетФИО плательщика и клиента не совпадают.
200163НетИдентификатор получателя не соответствует юридическому лицу.
200164НетНедостаточный уровень идентификации.
200165НетПополнение по этим реквизитам невозможно.
200171НетОшибка при проверке подписи.
200181НетОтсутствует успешный авторизационный запрос с переданным идентификатором.
200191ДаНа балансе контрагента недостаточно средств для проведения данной операции. Попробуйте позже.
200301НетПо техническим причинам пополнение невозможно.

Технические ошибки

HTTP-статусЗначение поля resultТип ошибки Повторить запрос Значение поля errMessageОписание
200400Техническая ошибкаДаПо техническим причинам пополнение невозможно. Рекомендуется повторить запрос.
400Техническая ошибкаНетBad RequestЗапрос составлен некорректно — ошибка валидации, JSON, структура.
401Техническая ошибкаНетUnauthorizedНе передан или невалиден токен доступа.
403Техническая ошибкаНетForbiddenДоступ к ресурсу запрещен — недостаточно прав.
422Техническая ошибкаНетUnprocessable EntityЗапрос синтаксически верен, но не может быть обработан — логическая ошибка.
429Техническая ошибкаДаToo Many RequestsПревышен лимит запросов. Рекомендуется повторить запрос.
500Техническая ошибкаДаInternal Server ErrorВнутренняя ошибка сервера. Рекомендуется повторить запрос позже.

Правила повторной отправки запроса

Если вы получили ответ, который требует повторной отправки запроса, значения полей data.sourceCode и data.sourceId должны совпадать со значениями оригинального запроса — иначе повторный запрос будет расценен как новый.

openapi@tbank.ru

АО «ТБанк» использует файлы «cookie» с целью персонализации сервисов и повышения удобства пользования веб-сайтом. «Cookie» представляют собой небольшие файлы, содержащие информацию о предыдущих посещениях веб-сайта. Если вы не хотите использовать файлы «cookie», измените настройки браузера.