Протокол взаимодействия с платежной системой
В данном документе описан регламент технического взаимодействия платежной системы «Абонент» с программным обеспечением агента по приему платежей по протоколу HTTP(S).
Документ предназначен для разработчиков программного обеспечения работающего на стороне агентов по приему платежей.
Содержание
- 1 Термины и определения
- 2 Общие принципы взаимодействия с Системой
- 3 Общее описание допустимых запросов к системе
- 4 Общая структура взаимодействия
- 4.1 Библиотека для формирования запросов к системе
- 4.2 Подпись данных с помощью библиотеки
- 4.3 Отправка запроса и получение результата
- 4.4 Запрос на проверку доступности платежной системы
- 4.5 Запрос на получение списка услуг
- 4.6 Запрос на получение информации по лицевому счету
- 4.7 Запрос на проведение платежа
- 4.8 Запрос на проверку статуса платежа
Термины и определения
Система – платежная система «Абонент».
Агент – организация, осуществляющая прием оплаты через платежную систему «Абонент».
Клиент - программное обеспечение Агента, реализующее клиентскую часть настоящего протокола.
Общие принципы взаимодействия с Системой
Взаимодействие с системой осуществляется в режиме запрос – ответ. Инициатором взаимодействия во всех случаях является Клиент.
Запрос
Представляет собой текстовый блок данных, структурированных в соответствии с требованиями формата JSON и настоящего Протокола. Для успешной обработки Запроса в нем обязательно должна присутствовать следующая информация.
- Код клиента - уникальный в рамках Системы номер точки, необходимый для идентификации Агента и последующей привязки платежей. Код клиента сообщается сотрудником нашей компании либо уточняется Агентом самостоятельно, с использованием Web-интерфейса.
- Электронно-цифровая подпись. Подпись выполняется на основании закрытого ключа, передаваемого Агенту перед началом программного взаимодействия. Ключ передается Агенту в виде сертификата - файла в формате X.509 версия 3. Запрещается передача этих сведений третьим лицам.
Электронно-цифровая подпись (ЭЦП) представляет собой строку, полученную по следующему алгоритму.
- Подписываемые данные, в виде JSON-строки преобразуются в массив байт в формате UTF-8.
- По полученному массиву байт вычисляется хэш-функция SHA-256 и сохраняется как массив байтов.
- По сохраненному массиву еще раз вычисляется хэш-функция пол алгоритму SHA1, т.е. в целом реализуется расчет вида SHA1(SHA256(<подписываемый блок данных>)).
- Полученный массив байтов шифруется алгоритмом RSA. В качестве ключа используется закрытый ключ Агента из сертификата.
- Полученный массив байтов преобразуется в строку Base64.
Запрос, представляет собой строку, полученную по следующему алгоритму.
- Формируется содержательная часть Запроса (строка подписываемых данных), включающая в себя "Код клиента" (ClientId), "Входные параметры" (Data), "Код операции" (Operation). Данные оформляются в виде текстовой строки в формате формата JSON.
- Согласно алгоритму, приведенному выше, формируется ЭЦП.
- Из полученной строки подписываемых данных, ЭЦП, а также некоторые дополнительных параметров ("Тип данных" и "Номер протокола") собираются окончательный Запрос.
Пример Запроса.
{
"DataFormat":0,
"ProtocolVersion":"v.1.0.0",
"SignedData":
{
"ClientId":468,
"Data":null,
"Operation":0
},
"Sign":"nPTR4MTSdrySDdqCXCWdXmlm0p1CxidxuYo="
}
Ответ
На каждый Запрос система возвращает результат выполнения запроса и описание результата выполнения (Ответ). Ответ также представляет собой текстовый блок, оформленный аналогично Запросу.
Пример Ответа.
{
"DataFormat":0,
"ProtocolVersion": "v.1.0.0",
"SignedData":
{
"OperationResult":{"ResultCode":-3,"CodeDescription":"Произошла ошибка","Message":"Указан неверный код клиента"},
"Data":null
},
"Sign":"nIhserSefhisreeiSh7REgW33D34="
}
В случае ошибки, система вернет также расширенное описание ошибки. Допустимы следующие результаты выполнения операций:
- 0 – запрос успешно обработан;
- -1 – некорректная подпись;
- -2 – версия протокола не поддерживается;
- -3 – произошла ошибка обработки запроса.
Данные Ответа, подписываются по тому же алгоритму, что и данные Запроса, однако в качестве ключа используется открытый ключ Агента. Это дает возможность проверить правильность полученных данных по следующему алгоритму.
- Блок SignedData Ответа преобразуется в массив байт.
- От полученного массива данных рассчитывается хэш-функция вида SHA1(SHA256(<подписываемый блок данных>)).
- Значение в блоке Sign декодируется из Base64 в массив байтов и расшифровывается алгоритмом RSA с использование закрытого ключа Агента.
- Полученные на предыдущих этапах массивы сравниваются. Ответ считается корректным только в том случае, если содержимое массивов идентично.
Алгоритм взаимодействия с системой
В общем виде алгоритм взаимодействия с системой представляет собой последовательное выполнение следующих шагов.
- Формируется Запрос.
- Сформированый Запрос отправляется для обработки Системе с помощью метода POST HTTP-протокола. Для взаимодействия с Системой используются следующие два адреса:
http://beta-online.abonentplus.ru - адрес, используемый для разработки, отладки и тестирования Клиента; http://online.abonentplus.ru - адрес, используемый для регулярной работы с Системой.
- 3. В ответ на запрос Система формирует Ответ, который принимается клиентом и анализируется.
Общее описание допустимых запросов к системе
В рамках настоящего Протокола Клиенту доступны пять основных операций, каждой из которых присвоен условный код. При формирование Запроса данный код указывается в поле Operation блока основных (подписываемых) данных.
Список доступных операций следующий.
- Проверить подключение (код 0).
- Провести платеж (код 1).
- Получить информацию по лицевому счету (код 2).
- Проверить статус платежа (код 3).
- Получить список доступных услуг (код 4).
Кроме того, по определенным типам запросов система может возвращать выходные параметры.
Набор входных и выходных параметров по каждому типу запроса описан в следующих разделах.
Проверить соединение
- Входные параметры – код клиента.
- Выходные параметры – отсутствуют.
Получить список услуг
- Входные параметры – код клиента.
- Выходные параметры:
- Код услуги или ресурса (в дальнейшем используется для формирования платежа).
- Наименование услуги или ресурса.
- Код организации, оказывающей услугу или поставляющей ресурс.
- Наименование организации, оказывающей услугу или поставляющей ресурс.
- Код типа лицевого счета, используемый для идентификации плательщика.
- Наименование типа лицевого счета, используемого для идентификации плательщика.
- Реквизиты организации для перечисления средств.
- Дополнительные поля для формирования платежа.
Получить данные по абоненту
- Входные параметры:
- Код типа лицевого счета.
- Лицевой счет.
- Выходные параметры:
- Код типа лицевого счета.
- Лицевой счет абонента.
- Список альтернативных лицевых счетов абонента с указанием типа.
- Список услуг абонента с информацией для приема платежа (текущая задолженность, признак наличия счетчика, последние показания счетчика и дата их съема, текущий тариф).
Зарегистрировать платеж
- Входные параметры:
- Уникальный номер платежа (Guid).
- Дата/время.
- Примечание.
- Другая информация.
- Зачисления - список сумм оплат, с разбивкой по услугам, с указанием для каждой услуги:
- Кода типа лицевого счета.
- Лицевого счета.
- Кода услуги.
- Суммы платежа.
- Дополнительные параметры (текущие показания счетчика, оплачиваемы объем и т.д.).
- Выходные параметры – результат обработки (поставлен в очередь, отклонен и т.д.)
Проверить статус платежа
- Входные параметры – уникальный номер платежа (Guid).
- Выходные параметры: список зачислений с указанием результатов обработки по каждому из зачислений (отправлено поставщику услуг/находится в очереди на обработку/ошибка и т.д.).
Общая структура взаимодействия
Инициатором обмена является ПО агента по приему платежей. Запросы посылаются через интернет, по протоколу HTTP(S) методом POST. Данные передаются в JSON-формате. Каждый запрос обязательно должен быть подписан с помощью ЭЦП агента.
Запрос должен содержать следующие поля:
- ProtocolVersion – версия протокола, строка.
- DataFormat- формат данных в поле Data. В настоящее время поддерживается только формат JSON, что соответствует значению 0 в данном поле.
- SignedData – подписываемые данные, структура
- ClientId – код клиента платежной системы, целое. Данный код выдается при подключении к платежной системе.
- Operation – тип операции, целое. Подробнее каждый тип операции будет рассмотрен ниже.
- Data – данные для выполнения операции, объект в JSON-формате.
- Sign – электронно-цифровая подпись, строка base64.
Библиотека для формирования запросов к системе
Для упрощения доступа к системе разработана специальная библиотека классов. Исходный код библиотеки на языке C# приведен в приложении к данному описанию.
Библиотека состоит из следующих основных классов.
Классы общего назначения:
- AbonentPaysystemRequest – запрос к платежной системе;
- AbonentPaysystemResponse – ответ от платежной системы;
- ExchangeResult – результат выполнения операции;
- RequestSignedData – входные данные для запроса;
- ResponseSignedData – выходные данные;
- RSASignHelper – класс, позволяющий подписывать данные с помощью сертификата.
Классы для проведения платежей:
- Pay – платеж;
- Enlistment – зачисление.
Классы для получения информации по абоненту:
- Abonent – абонент;
- AbonentAccount – сведения о лицевом счете абонента, с привязкой к поставщику услуг;
- AbonentBalance – информация по услуге (долги, показания счетчика и т.д.).
Классы для получения списка услуг:
- PaymentDestination – услуга.
Подпись данных с помощью библиотеки
Пример исходного кода для подписи строки:
// Открываем файл сертификата
var cert = new X509Certificate2(Path, Password);
// Создаем класс для выполнения подписи
var signHelper = new RSASignHelper(cert);
// Выполняем подпись с помощью класса-помощника
var Sign = Convert.ToBase64String(signHelper.GetSign(Data));
Отправка запроса и получение результата
Пример исходного кода:
- requestData – объект, содержащий исходные данные для выполнения запроса к системе;
- response – результат, который возвращает система.
// Отправляем запрос
WebRequest webRequest = WebRequest.Create(url.Text);
webRequest.Method = "POST";
webRequest.Timeout = 100000;
webRequest.ContentType = "application/json";
var sentData = Encoding.UTF8.GetBytes(requestData.ToJson());
webRequest.ContentLength = sentData.Length;
var sendStream = webRequest.GetRequestStream();
sendStream.Write(sentData, 0, sentData.Length);
sendStream.Close();
WebResponse res = webRequest.GetResponse();
// Получаем результаты
var ReceiveStream = res.GetResponseStream();
var sr = new StreamReader(ReceiveStream, Encoding.UTF8);
var response = AbonentPaysystemResponse.FromJson(sr.ReadToEnd());
Запрос на проверку доступности платежной системы
Для проверки доступности платежной системы необходимо отправить запрос с Operation = 0 и с пустым полем Data на адрес платежной системы. В данном примере приведены все операции – от формирования запроса, до его подписи и отправки в систему. Пример исходного кода:
// Создаем запрос
var requestData = new AbonentPaysystemRequest()
{
SignedData = new RequestSignedData()
{
ClientId = 1,
Operation = OperationType.Check,
},
ProtocolVersion = "v.1.0.0",
Sign = "",
};
// Подписываем
var cert = new X509Certificate2(Path, Password);
var signHelper = new RSASignHelper(cert);
requestData.Sign = Convert.ToBase64String(signHelper.GetSign(requestData.SignedData.ToJson()));
// Отправляем запрос
WebRequest webRequest = WebRequest.Create(url.Text);
webRequest.Method = "POST";
webRequest.Timeout = 100000;
webRequest.ContentType = "application/json";
var sentData = Encoding.UTF8.GetBytes(requestData.ToJson());
webRequest.ContentLength = sentData.Length;
var sendStream = webRequest.GetRequestStream();
sendStream.Write(sentData, 0, sentData.Length);
sendStream.Close();
WebResponse res = webRequest.GetResponse();
// Получаем результаты
var ReceiveStream = res.GetResponseStream();
var sr = new StreamReader(ReceiveStream, Encoding.UTF8);
var response = AbonentPaysystemResponse.FromJson(sr.ReadToEnd());
Запрос на получение списка услуг
Пример исходного кода:
// Создаем запрос
var request = new AbonentPaysystemRequest()
{
SignedData = new RequestSignedData()
{
ClientId = 1,
Operation = OperationType.GetPaymentDestinations,
},
ProtocolVersion = "v.1.0.0",
Sign = "",
};
// Подписываем
…………
// Отправляем запрос
…………
// Получаем результаты
var response = AbonentPaysystemResponse.FromJson(sr.ReadToEnd());
// Отображаем результаты
var paymentDestinations = PaymentDestinations.FromJson(response.SignedData.Data);
Запрос на получение информации по лицевому счету
Пример исходного кода:
// Создаем запрос
var request = new AbonentPaysystemRequest()
{
SignedData = new RequestSignedData()
{
ClientId = 1,
Operation = OperationType.GetAccountInfo,
},
ProtocolVersion = "v.1.0.0",
Sign = "",
};
// Формируем лицевой счет для запроса
var account = new AbonentAccount()
{
Account = “00000000”,
SupplierId = 1,
};
// Передаем лицевой счет в запрос
request.SignedData.Data = account.ToJson();
//Подписываем
…………
//Отправляем запрос
…………
//Получаем результаты
var response = AbonentPaysystemResponse.FromJson(sr.ReadToEnd());
//Отображаем результаты
var paymentDestinations = PaymentDestinations.FromJson(response.SignedData.Data);
Запрос на проведение платежа
Пример исходного кода:
// Создаем запрос
var request = new AbonentPaysystemRequest()
{
SignedData = new RequestSignedData()
{
ClientId = 1,
Operation = OperationType.GetAccountInfo,
},
ProtocolVersion = "v.1.0.0",
Sign = "",
};
// Формируем платеж
var pay = new Pay
{
Enlistments = new List<Enlistment>(),
Id = Guid.NewGuid(),
};
pay.PayDateTime = DateTime.Now;
pay.Enlistments.Add(new Enlistment()
{
Account = PayAccount.Text,
PaymentDestinationId = 1,
PAmmount = 0,
CAmmount = 0,
Id = Guid.NewGuid(),
});
// Передаем платеж в запрос
request.SignedData.Data = pay.ToJson();
// Подписываем
…………
// Отправляем запрос
…………
// Получаем результаты
var response = AbonentPaysystemResponse.FromJson(sr.ReadToEnd());
Запрос на проверку статуса платежа
Пример исходного кода:
// Создаем запрос
var request = new AbonentPaysystemRequest()
{
SignedData = new RequestSignedData()
{
ClientId = 1,
Operation = OperationType.GetAccountInfo,
},
ProtocolVersion = "v.1.0.0",
Sign = "",
};
// Передаем ID платежа в запрос
request.SignedData.Data = Id;
//Подписываем
…………
//Отправляем запрос
…………
//Получаем результаты
var response = AbonentPaysystemResponse.FromJson(sr.ReadToEnd());