Протокол обмена данными
Общие сведения
Протокол пакетного обмена создан для удобства одновременного проведения большого количества платежей, а также для повышения удобства реализации клиентского ПО, за счет переноса части клиентской логики на сервер.
Запросы должны отправляться на следующий URL: https://188.133.220.43/term2/term2/xml.jsp
Процедура обмена включает следующие этапы:
Шаг 1. Опрос баланса
Отправка запросов на сервер осуществляется по HTTP протоколу, методом POST.
Пример запроса баланса:
<?xml version="1.0" encoding="utf-8"?> <request> <protocol-version>4.00</protocol-version> <request-type>3</request-type> <terminal-id>123</terminal-id> <extra name="login">S1</extra> <extra name="sign-md5">S2</extra> </request>
Описание:
Параметры запроса помещаются в элемент <request>.
Тег <request> включает в себя следующие теги:
- <protocol-version> – данный тег содержит номер версии протокола обмена;
- <request-type> – тип запроса 3;
- <terminal-id> – идентификатор, с которого осуществляется платеж;
- <extra> – тег описывает данные авторизации: S1 – логин пользователя (кассира), S2 – Хэш-подпись пакета на отправку (см. Приложение А).
Ответ сервера:
<response requestTimeout="60"> <extra name="balance">6.5600</extra> <extra name="overdraft">0.0000</extra> </response
Описание:
- requestTimeout – рекомендуемый сервером интервал запроса статуса платежей в секундах. Вы можете использовать это число для отсчета времени (в секундах) перед запросом статуса. К указанному времени все платежи, посланные на обработку, должны быть проведены.
- extra описывает составные части баланса: balance – баланс агента, overdraft – выставленный кредитный лимит. Общий баланс равен balance+overdraft.
Шаг 2. Онлайн проверка платежа
Пример запроса онлайн проверки:
<?xml version="1.0" encoding="utf-8"?> <request> <protocol-version>4.00</protocol-version> <request-type>10</request-type> <terminal-id>123</terminal-id> <extra name="login">S1</extra> <extra name="sign-md5">S2</extra> <check count="1" to-amount="50"> <payment> <transaction-number>123456789</transaction-number> <to> <amount>50</amount> <service-id>2</service-id> <account-number>1234567890</account-number> </to> </payment> </check> </request>
Описание:
Параметры запроса помещаются в элемент <request>.
Тег <request> включает в себя следующие теги:
- <protocol-version> – данный тег содержит номер версии протокола обмена;
- <request-type> – тип запроса 3;
- <terminal-id> – идентификатор, с которого осуществляется платеж;
- <extra> – тег описывает данные авторизации: S1 – логин пользователя (кассира), S2 – хэш-подпись пакета на отправку (см. Приложение А).
Тег <check> содержит перечень платежей на проверку и включает в себя следующие теги:
- <payment> – тег, содержащий данные о платеже
<request> ... <check> <payment> ... </payment> </check > </request>
Тег <payment> описывает конкретные платежи и включает в себя следующие теги:
- <transaction-number> – номер транзакции на терминале. Пара номер транзакции + номер терминала должны быть всегда уникальны;
- <to> – информация о платеже: сумма, номер счета, идентификатор провайдера. Тег содержит дочерние теги:
- <amount> – сумма к зачислению на счет;
- <service-id> – идентификатор сервиса, на который производится зачисление средств (идентификатор провайдера).
- <account-number> – идентификатор абонента в информационной системе провайдера (номер сотового телефона или номер лицевого счета);
- <receipt> – информация о выданном чеке. Тег содержит дочерние теги:
- <datetime> – дата распечатки чека в формате yyyymmddhhnnss;
- <receipt-number> – номер чека – число 0..999999 последовательно закольцовано;
Ответ сервера:
<response> <request-type>1</request-type> <status-id>30</status-id> <extra name="disp1">Иванов Иван Иванович</extra> </response>
Описание:
- <status-id> – код результата онлайн проверки: 30 – успешная проверка, 28 не успешная;
- <extra> описывает составные части онлайн проверки: disp1 – текстовый результат проверки.
Шаг 3. Отправка запроса на проведение платежей
Пример запроса баланса:
<?xml version="1.0" encoding="utf-8"?> <request> <protocol-version>4.00</protocol-version> <request-type>10</request-type> <terminal-id>123</terminal-id> <extra name="login">S1</extra> <extra name="sign-md5">S2</extra> <auth> <payment> <transaction-number>N1</transaction-number> <to> <amount>N3</amount> <service-id>N4</service-id> <account-number>N5</account-number> </to> <fields> <field id="1">N7</field> <field id="2">N8</field> </fields> <receipt> <datetime>D1</datetime> <receipt -number>N6</receipt-number> </receipt> <extra name="S1">S2</extra> </payment> </auth> </request>
Описание:
Параметры запроса помещаются в элемент <request>. Тег <request> включает в себя следующие теги:
- <protocol-version> – данный тег содержит номер версии протокола обмена;
- <request-type> – тип запроса;
- <terminal-id> – идентификатор, с которого осуществляется платеж;
- <extra> – тег описывает данные авторизации: S1 – логин пользователя (кассира), S2 - хэш-подпись пакета на отправку (см. Приложение А).
Тег <auth> содержит перечень платежей на отправку и включает в себя следующие теги:
- <payment> – тег, содержащий данные о платеже
<request> ... <auth> <payment> ... </payment> <payment> ... </payment> <payment> ... </payment> </auth> </request>
Тег <payment> описывает конкретные платежи и включает в себя следующие теги:
- <transaction-number> – номер транзакции на терминале. Пара номер транзакции + номер терминала должны быть всегда уникальны;
- <to> – информация о платеже: сумма, номер счета, идентификатор провайдера. Тег содержит дочерние теги:
- <amount> – сумма к зачислению на счет;
- <service-id> – идентификатор сервиса, на который производится зачисление средств (идентификатор провайдера);
- <account-number> – идентификатор абонента в информационной системе провайдера (номер сотового телефона или номер лицевого счета);
- <fields> – информация о дополнительных полях для проведения платежа. Тег содержит дочерние теги:
- <field id=«1»> – дополнительное поле 1;
- < field id=«N»> – дополнительное поле N;
- <receipt> – информация о выданном чеке. Тег содержит дочерние теги:
- <datetime> – дата распечатки чека в формате yyyymmddhhnnss;
- <receipt-number> – номер чека – число 0..999999 последовательно закольцовано;
- <extra> – служебные поля, например, комментарий:
<extra name=«comment»>это комментарий</extra>
Ответ сервера:
После отправки запроса на сервер, в ответ приходит пакет с результатами добавления транзакций в базу:
<response requestTimeout=N1> <payment status =N2 transaction-number=N3 result-code=N4> ... </payment> ... </response>
Описание:
- requestTimeout – рекомендуемый сервером интервал запроса статуса платежей в секундах. Вы можете использовать это число для отсчета времени (в секундах) перед запросом статуса . К указанному времени все платежи, посланные на обработку, должны быть проведены.
- status – статус транзакции после добавления в базу. Нормальным результатом добавления транзакции считается статус 25. Все остальные статусы могут возникать в результате исключительных ситуаций и по вопросам их возникновения необходимо обращаться в службу поддержки.
- transaction-number – номер транзакции, добавленной в базу;
- result-code – код обработки операции.
Шаг 4. Запрос о состоянии платежей
После добавления транзакции на сервере запускается процедура авторизации и проведения платежа, которая отправляет провайдеру запрос на проверку возможности проведения платежа и в случае положительного ответа провайдера – посылает команду на проведение. Каждый шаг этой операции сопровождается промежуточными статусами и кодами завершения. А также после успешного или ошибочного завершения операции, транзакции присваивается определенный статус и код результата завершения. В любой момент клиентское ПО может обратиться к серверу и опросить текущий статус транзакции и код результата завершения:
Пример запроса баланса:
<request> ... <status> <payment> <transaction-number>1</transaction-number> </payment> <payment> <transaction-number>2</transaction-number> </payment> <payment> <transaction-number>3</transaction-number> </payment> </status> </request
Описание:
- <status> – содержит транзакции, по которым нужно узнать статус;
- <payment> – информация о платеже. Тег содержит дочерний тег: - <transaction-number> – номер транзакции, по которой необходимо узнать текущее состояние.
Ответ сервера:
После отправки запроса на сервер, в ответ приходит пакет с результатами обработки запрашиваемых транзакций:
<response> <payment transaction-number="N1" status="N2" result-code="N3" final-status="B1" fatal-error="B2"> ... </payment> ... </response>
Описание:
- transaction-number – номер транзакции, для которой указан статус
- status – код текущего статуса транзакции;
- result-code – код завершения операции;
- final-status:
- false – статус промежуточный и обработка транзакции продолжается, необходим повторный запрос статуса для этой транзакции;
- true – статус является окончательным. Обработка транзакции прекращена сервером.
- fatal-error:
- false – если значение final-status – true (сервер прекратил обработку платежа), повторная отправка этого платежа на сервер, но с другим номером транзакции, даст другой результат (возможно платеж пройдет);
- true – обработка платежа завершена в результате фатальной ошибки, повторная отправка платежа с другим номером транзакции приведет к повторению той же ошибки.
ПРИЛОЖЕНИЕ А: АВТОРИЗАЦИЯ С ПОМОЩЬЮ ПОДПИСИ
Для обеспечения большей безопасности, при пересылке платежных пакетов вы можете использовать авторизацию с помощью специальной подписи (элемент sign-md5), которая формируется по следующему алгоритму:
- Каждый элемент transaction-number складывается с MD5 от пароля:
transaction-number+password-md5
- Осуществляется MD5 хеширование результирующей строки. В результате будет получена строка MD5 последовательности из 32 байт:
md5(transaction-number+password-md5))
- Все полученные MD5 последовательности (для каждого элемента transaction-number) необходимо перевести в битовые массивы, соответствующие шестнадцатеричным кодам, и сложить по модулю 2 (XOR):
сумма_транзакций=сумма_ транзакций XOR md5(transaction-number+password-md5))
- Преобразовать полученный в результате всех операций битовый массив в строку, содержащую 32 символа шестнадцатеричных.
- Полученную строку (длиной 32 символа) необходимо сложить с логином, номером терминала, номером запроса, MD5 от пароля:
login+password-md5+terminal-id+request-type +сумма_транзакций
- Осуществляется MD5 хеширование результирующей строки:
sign-md5=md5(login+password_md5+terminal-id+request-type+сумма_транзакций)
- Полученная последовательность записывается в элемент
<extra name=«sign-md5»>
.
Например:
<extra name="sign-md5">81164E9C056CEF02F90E671559D6D4BF</extra>
Пример 1. Пример формирования подписи на JAVA
/* * * Function for getting OSMP sign-md5 from Document (Represents source XML) * @param doc Документ, сформированный из подписываемой XML * @param login Логин пользователя * @param passMD5 md5 от пароля пользователя * @return Подпись пакета * @throws NoSuchAlgorithmException */ private String getSign(Document doc , String login, String passMD5) throws NoSuchAlgorithmException { // Получаем id терминала // Получаем тип запроса // Получаем суммы транзакций // Формируем подпись из строки return md5(login + passMD5 + termin al_id + request_type + txn_sum); } /** * Функция получения общей суммы md5 подписей номеров транзакций * @param doc Документ, сформированный из подписываемой XML * @param passMD5 Документ, сформированный из подписываемой XML * @return Строка с md5 подписью номеров * @throws NoSuchAlgorithmException */ private String getSignTxnSum (Document doc, String passMD5) throws NoSuchAlgorithmException { NodeList requestNodeList = doc.getElementsByTagName("request"); NodeList nl = ((Element) requestNodeList.item(0)).getElementsByTagName ("payment"); byte[] sum = new byte[16]; for (int i = 0; i < sum.length; i++) { sum[i]=0; } MessageDigest md = MessageDigest.getInstance("MD5"); if (nl.getLength()== 0) return ""; //Проходим по всем номерам транзакций. for (int i = 0; i < nl.getLength(); i++) { String txn_id = getTextNode(nl.item(i), "transaction-number"); // код ошибки (0 - все ОК) if (txn_id!=null & & txn_id.length ()>0) { //Берем md5 подпись от номера транзакции + пароль пользователя byte[] buf = md.digest((txn_id + passMD5) .getBytes()); //Полученный байтовый массив суммируем sum = xorArray (sum, buf); } } StringBuffer sb = new StringBuffer(); // Преобразуем полученный массив в строковое представление в hex for (byte aSum : sum) { String hex = "00" + Integer.toHexString(aSum); sb.append(hex.substring(hex.length() - 2)); } return sb.toString().toUpperCase(); } //Функция суммирования массивов. private byte [] xorArray(byte [] a, byte [] b) { if(b.length != a.length) throw new IllegalArgumentException("length of byte [] b must be >= byte [] a"); byte [] c = new byte[a.length]; for(int i =0;i< a.length;i++) { c[i] = (byte)(a[i] ^ b[i]); } return c; } //Функция получения строкового представления md5 от строки public static String md5(String passw) { try { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] buf = md.digest(passw.getBytes()); StringBuffer sb = new StringBuffer(); for (byte aBuf : buf) { String hex = "00" + Integer.toHexString(aBuf); sb.append(hex.substring(hex.length() - 2)); } return sb.toString().toUpperCase(); } catch (NoSuchAlgorithmException e) { return null; } } // Функция получения текстового элемента их xml документа public static String getTextNode(Node node, String tagName) { NodeList nl = null; if (node instanceof Element) nl = ((Element) node).getElementsByTagName(tagName); else if (node instanceof Document) nl = ((Document) node).getElementsByTagName(tagName); if (nl == null) return null; if (nl.getLength() < 1 ) return null; Node n = nl.item(0); if (!n.hasChildNodes()) return null; n = n.getFirstChild(); if (n instanceof Text) return n.getNodeValue(); return null; }
ПРИЛОЖЕНИЕ B: СТАТУСЫ ПЛАТЕЖЕЙ
Возможные значения поля status:
Значение | Описение |
10 | Платеж принят |
25 | В процессе |
51 | Успешно проведен |
160 | Платеж отлонен |
ПРИЛОЖЕНИЕ С: КОДЫ ОШИБОК
Возможные значения поля result-code:
0 | Успешно обработан |
3 | Техническая ошибка, нельзя отправить запрос провайдеру |
4 | Неверная сумма платежа |
5 | Провайдер временно недоступен |
90 | Проведение платежа не окончено |
111 | Прием платежа запрещен, обратитесь в техподдержку |
130 | Работа с данным провайдером не реализована |
150 | Ошибка авторизации |
151 | Ошибка при обработке входящего xml |
215 | Транзакция с таким номером уже есть в базе |
220 | Недостаточно средств для проведения платежа |