Протокол взаимодействия с платежной системой

Материал из doc.abonent.plus
Перейти к: навигация, поиск

В данном документе описан регламент технического взаимодействия платежной системы «Абонент» с программным обеспечением агента по приему платежей по протоколу HTTP(S).

Документ предназначен для разработчиков программного обеспечения работающего на стороне агентов по приему платежей.  

Термины и определения

Система – платежная система «Абонент».

Агент – организация, осуществляющая прием оплаты через платежную систему «Абонент».

Клиент - программное обеспечение Агента, реализующее клиентскую часть настоящего протокола.

Общие принципы взаимодействия с Системой

Взаимодействие с системой осуществляется в режиме запрос – ответ. Инициатором взаимодействия во всех случаях является Клиент.

Запрос

Представляет собой текстовый блок данных, структурированных в соответствии с требованиями формата JSON и настоящего Протокола. Для успешной обработки Запроса в нем обязательно должна присутствовать следующая информация.

  • Код клиента - уникальный в рамках Системы номер точки, необходимый для идентификации Агента и последующей привязки платежей. Код клиента сообщается сотрудником нашей компании либо уточняется Агентом самостоятельно, с использованием Web-интерфейса.
  • Электронно-цифровая подпись. Подпись выполняется на основании закрытого ключа, передаваемого Агенту перед началом программного взаимодействия. Ключ передается Агенту в виде сертификата - файла в формате X.509 версия 3. Запрещается передача этих сведений третьим лицам.

Электронно-цифровая подпись (ЭЦП) представляет собой строку, полученную по следующему алгоритму.

  1. Подписываемые данные, в виде JSON-строки преобразуются в массив байт в формате UTF-8.
  2. По полученному массиву байт вычисляется хэш-функция SHA-256 и сохраняется как массив байтов.
  3. По сохраненному массиву еще раз вычисляется хэш-функция пол алгоритму SHA1, т.е. в целом реализуется расчет вида SHA1(SHA256(<подписываемый блок данных>)).
  4. Полученный массив байтов шифруется алгоритмом RSA. В качестве ключа используется закрытый ключ Агента из сертификата.
  5. Полученный массив байтов преобразуется в строку Base64.

Запрос, представляет собой строку, полученную по следующему алгоритму.

  1. Формируется содержательная часть Запроса (строка подписываемых данных), включающая в себя "Код клиента" (ClientId), "Входные параметры" (Data), "Код операции" (Operation). Данные оформляются в виде текстовой строки в формате формата JSON.
  2. Согласно алгоритму, приведенному выше, формируется ЭЦП.
  3. Из полученной строки подписываемых данных, ЭЦП, а также некоторые дополнительных параметров ("Тип данных" и "Номер протокола") собираются окончательный Запрос.

Пример Запроса.

{
  "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 – произошла ошибка обработки запроса.

Данные Ответа, подписываются по тому же алгоритму, что и данные Запроса, однако в качестве ключа используется открытый ключ Агента. Это дает возможность проверить правильность полученных данных по следующему алгоритму.

  1. Блок SignedData Ответа преобразуется в массив байт.
  2. От полученного массива данных рассчитывается хэш-функция вида SHA1(SHA256(<подписываемый блок данных>)).
  3. Значение в блоке Sign декодируется из Base64 в массив байтов и расшифровывается алгоритмом RSA с использование закрытого ключа Агента.
  4. Полученные на предыдущих этапах массивы сравниваются. Ответ считается корректным только в том случае, если содержимое массивов идентично.

Алгоритм взаимодействия с системой

В общем виде алгоритм взаимодействия с системой представляет собой последовательное выполнение следующих шагов.

  1. Формируется Запрос.
  2. Сформированый Запрос отправляется для обработки Системе с помощью метода POST HTTP-протокола. Для взаимодействия с Системой используются следующие два адреса:
http://beta-online.abonentplus.ru - адрес, используемый для разработки, отладки и тестирования Клиента;
http://online.abonentplus.ru - адрес, используемый для регулярной работы с Системой.
3. В ответ на запрос Система формирует Ответ, который принимается клиентом и анализируется.

Общее описание допустимых запросов к системе

В рамках настоящего Протокола Клиенту доступны пять основных операций, каждой из которых присвоен условный код. При формирование Запроса данный код указывается в поле Operation блока основных (подписываемых) данных.

Список доступных операций следующий.

  1. Проверить подключение (код 0).
  2. Провести платеж (код 1).
  3. Получить информацию по лицевому счету (код 2).
  4. Проверить статус платежа (код 3).
  5. Получить список доступных услуг (код 4).

Кроме того, по определенным типам запросов система может возвращать выходные параметры.

Набор входных и выходных параметров по каждому типу запроса описан в следующих разделах.

Проверить соединение

  1. Входные параметры – код клиента.
  2. Выходные параметры – отсутствуют.

Получить список услуг

  1. Входные параметры – код клиента.
  2. Выходные параметры:
    1. Код услуги или ресурса (в дальнейшем используется для формирования платежа).
    2. Наименование услуги или ресурса.
    3. Код организации, оказывающей услугу или поставляющей ресурс.
    4. Наименование организации, оказывающей услугу или поставляющей ресурс.
    5. Код типа лицевого счета, используемый для идентификации плательщика.
    6. Наименование типа лицевого счета, используемого для идентификации плательщика.
    7. Реквизиты организации для перечисления средств.
    8. Дополнительные поля для формирования платежа.

Получить данные по абоненту

  1. Входные параметры:
    1. Код типа лицевого счета.
    2. Лицевой счет.
  2. Выходные параметры:
    1. Код типа лицевого счета.
    2. Лицевой счет абонента.
    3. Список альтернативных лицевых счетов абонента с указанием типа.
    4. Список услуг абонента с информацией для приема платежа (текущая задолженность, признак наличия счетчика, последние показания счетчика и дата их съема, текущий тариф).

Зарегистрировать платеж

  1. Входные параметры:
    1. Уникальный номер платежа (Guid).
    2. Дата/время.
    3. Примечание.
    4. Другая информация.
    5. Зачисления - список сумм оплат, с разбивкой по услугам, с указанием для каждой услуги:
      • Кода типа лицевого счета.
      • Лицевого счета.
      • Кода услуги.
      • Суммы платежа.
      • Дополнительные параметры (текущие показания счетчика, оплачиваемы объем и т.д.).
  2. Выходные параметры – результат обработки (поставлен в очередь, отклонен и т.д.)

Проверить статус платежа

  1. Входные параметры – уникальный номер платежа (Guid).
  2. Выходные параметры: список зачислений с указанием результатов обработки по каждому из зачислений (отправлено поставщику услуг/находится в очереди на обработку/ошибка и т.д.).

Общая структура взаимодействия

Инициатором обмена является ПО агента по приему платежей. Запросы посылаются через интернет, по протоколу HTTP(S) методом POST. Данные передаются в JSON-формате. Каждый запрос обязательно должен быть подписан с помощью ЭЦП агента.

Запрос должен содержать следующие поля:

  1. ProtocolVersion – версия протокола, строка.
  2. DataFormat- формат данных в поле Data. В настоящее время поддерживается только формат JSON, что соответствует значению 0 в данном поле.
  3. SignedData – подписываемые данные, структура
    1. ClientId – код клиента платежной системы, целое. Данный код выдается при подключении к платежной системе.
    2. Operation – тип операции, целое. Подробнее каждый тип операции будет рассмотрен ниже.
    3. Data – данные для выполнения операции, объект в JSON-формате.
  4. 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());