Интеграция с внешними системами

Из структуры биллинга можно определить два способа взаимодействия с ним извне:

  • Обращение к базе данных - допустимо для выборок данных либо для быстрого внесения изменений, не предполагающих реакции сервера;

  • Обращение к серверу биллинга - выполнение действий аналогично оператору из АРМ биллинга посредством обращений сторонней системы.

При выполнении обращений к серверу биллинга помимо записи данных в БД могут производится различные дополнительные обработки самим сервером. Например: разблокировка модулей по платежу.

К серверу биллинга возможно обращаться из сторонних приложений посредством HTTP запросов. Пример запросов можно изучить вызывая различные действия в клиентском приложении, запущенном в через client_debug.bat (.sh). Запросы и ответы распечатываются в log файл. Биллинг поддерживает несколько вариантов протоколов обращений для различных действий, их можно определить по внешнему виду запросов.

HTTP Action

Более ранний протокол. Подразумевает передачу параметров в HTTP запросе с получением XML ответа. Примерный вид запроса и ответа в логе клиента:

http://billing:8081/executer?module=npay&action=ServiceSetList&mid=6&ABillingSecret=ONM13dhRxs8VDD9wFCzpPOrU&
[ length = 159 ] xml = <?xml version="1.0" encoding="UTF-8"?><data secret="B802E452DF43140146D0EC4219C847D1" status="ok"><list><item id="0" title="Полный набор услуг"/></list></data>

Дополнительно необходимо добавить в запрос параметры user и pswd с логином и паролем пользователя биллинга, от лица которого отправляется запрос. Рекомендуется добавить к запросу параметр authToSession=0, это предотвратит создание HTTP сессий, уменьшит потребление памяти на сервере.

В целях отладки запросы можно отправлять прямо в браузере.

Web-сервис

Более новые вызовы реализованы как Web-сервисы, пример обращения к ним вы можете посмотреть здесь. Используется Basic авторизация.

Примерный вид запроса и ответа:

http://billing:8081/executer/ru.avantis.abilling.kernel.module/ServiceService?wsdl -> {http://service.common.module.kernel.abilling.avantis.ru/}ServiceService:serviceList
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns5:serviceList xmlns:ns5="http://service.common.module.kernel.abilling.avantis.ru/" xmlns:common="http://common.avantis.ru" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><moduleId>9</moduleId></ns5:serviceList></S:Body></S:Envelope>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Header/><S:Body><ns5:serviceListResponse xmlns:ns5="http://service.common.module.kernel.abilling.avantis.ru/" xmlns:common="http://common.avantis.ru" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xml="http://www.w3.org/XML/1998/namespace"><return id="15" moduleId="9" title="Рекламный блок на Board.ufanet.ru в одном разделе (справа)" unit="0" using="true"/><return id="7" moduleId="9" title="Рекламный блок на Board.ufanet.ru в разделе &quot;Авторынок&quot; (справа)" unit="0" using="true"/><return id="12" moduleId="9" title="Рекламный блок на Board.ufanet.ru в разделе &quot;Аудио, видео, фототехника&quot; (справа)" unit="0" using="true"/><return id="6" moduleId="9" title="Рекламный блок на Board.ufanet.ru в разделе &quot;Компьютеры&quot; (справа)" unit="0" using="true"/>

Web-сервис через JSON RPC

Для более простого обращения к Web сервисам возможно использование протокола JSON RPC.

Запрос выглядит следующим образом, пример:

http://127.0.0.1:8080/abilling/executer/json/ru.avantis.abilling.kernel.contract.api/ContractService

{"method" : "contractList",
"user" :{ "user" : "shamil", "pswd" : "xxxx" },
"params" : {
"title" : "0",
"fc" : -1,
"groupMask" : 0,
"subContracts" : false,
"closed" : true,
"hidden" : false,
"page" : { "pageIndex" : 2, "pageSize" : 2 }
} }

URL запроса определяет Web-сервис, JSON запрос передаётся в теле запроса, кодировка UTF-8. Обязательные параметры:

  • method - вызываемая функция сервиса;

  • user - объект с логином и паролем пользователя, от лица которого выполняется действие;

  • params - объект со всем остальными параметрами сервиса.

Обязательно указание значений всех параметров с примитивными типами: int, boolean.

Примерный вид корректного ответа:

{"status":"ok","message":"",
"data":
{
"page":{"pageSize":2,"pageIndex":2,"pageCount":49,"recordCount":97,"pageFirstRecordNumber":2},
"return":
[{"id":353023,"title":"0022010","groups":0,"password":"bg2rFZ2PEX","dateFrom":"2010-01-02","dateTo":null,"balanceMode":0,"paramGroupId":14,"personType":0,"comment":"","hidden":false,"superCid":0,"dependSubList":"","status":0,"statusTimeChange":"2010-01-13","titlePatternId":0,"balanceSubMode":0,"sub":false,"independSub":false,"balanceLimit":0.00,"super":false,"dependSub":false},
{"id":353209,"title":"06-10-10/И-Г/0","groups":0,"password":"9351220759","dateFrom":"2010-10-06","dateTo":null,"balanceMode":1,"paramGroupId":14,"personType":0,"comment":"","hidden":false,"superCid":0,"dependSubList":"","status":0,"statusTimeChange":"2010-10-06","titlePatternId":0,"balanceSubMode":0,"sub":false,"independSub":false,"balanceLimit":0.00,"super":false,"dependSub":false}]}}

В status возвращается ok в случае корректного ответа, либо error - ошибка. При этом в message выводится текст ошибки.

Там выглядит сообщение об ошибке:

{"status":"error","message":"Неправильный пароль.","data":{}}

В случае корректного ответа в data возвращаются результаты выполнения. Возвращаемый методом параметр под ключом return.

Также возможен возврат результатов из параметров сервиса посредством объекта типа javax.xml.ws.Holder.

Для работы с сервисом необходимо найти его класс в JavaDoc, например: ContractService. Далее определить имена и типы передаваемых параметров, переходя к JavaDoc описаниям других классов, если понадобится.

Javadoc является первичным при определении имени параметров. Например Если в InetServ есть метод getPassword(), значит нужно использовать password как имя атрибута в JSON. Если смотреть лог работы клиента, там передается другой атрибут passw, в данном случае javadoc является первичным.

Некоторую сложность представляет передача параметров, в роли которых могут выступать классы-потомки указанного в JavaDoc класса. Для примера рассмотрим параметр entityFilter указанного ранее сервиса, метод contractList. В качестве параметров передаются наследники объекта FilterEntityAttr. В JavaDoc данного класса находим:

@JsonTypeInfo(use=NAME,
               include=PROPERTY,
              property="type")
@JsonSubTypes(value={
@JsonSubTypes.Type(name="Address",value=FilterEntityAttrAddress.class),
@JsonSubTypes.Type(name="Date",value=FilterEntityAttrDate.class),
@JsonSubTypes.Type(name="House",value=FilterEntityAttrHouse.class),
@JsonSubTypes.Type(name="Int",value=FilterEntityAttrInt.class),
@JsonSubTypes.Type(name="List",value=FilterEntityAttrList.class),
@JsonSubTypes.Type(name="Text",value=FilterEntityAttrText.class),
@JsonSubTypes.Type(name="Email",value=FilterEntityAttrEmail.class)})

Данные строки означают, что объекты маркируются дополнительным полем type, в зависимости от которого определяется класс переданного объекта. Вот так, например, выглядит запрос фильтрации договоров по текстовому параметру:

{"method" : "contractList",
"user" :{ "user" : "shamil", "pswd" : "xxxx" },
"params" :
{
"fc" : -1,
"groupMask" : 0,
"subContracts" : false,
"closed" : true,
"hidden" : false,
"page" : { "pageIndex" : 1, "pageSize" : 2 },
"entityFilter" : [ { "type" : "Text", "entitySpecAttrIds" : [2], "value" : "1"  } ]
}  }

Для тестирования запросов удобно использовать плагин браузера позволяющий отправку запросов (типа HttpRequester для FF), либо штатную возможность браузера.

Web API

Для интеграции ABilling с внешними сайтами или стороним Личным кабинетом, возможно использование механизм Web API (доступен с версии 6.2)

Для активации данного API в конфигурации ядра необходимо прописать

web.api.enable=true
Запрос к Web API не проверяется на аутентификацию и права пользователя, поэтому при его включении нужно изолировать доступ к данному URL.

После активации, будeт доступны два режима получения данных из ABilling:

  • в XML формате (:port/abilling/xmlWebApi/<operation>)

  • в JSON формате (:port/abilling/jsonWebApi/<operation>)

    Где *<operation>* это:

для Ядра

  • login

  • contractParameters

  • contractBalance

  • contractPayments

  • lastContractPayments

  • contractTarifPlans

  • contractTariffOptions

  • contractModules

для других модулей - в разработке, дополнительная информация по запросу на e-mail (http://abilling.ru) или на форуме.

Операция login

пример запроса - /xmlWebApi/login?login=kirill&password=[&midAuth=0] или /jsonWebApi/login?login=kirill&password=[&midAuth=0]*

ответы:

<response><status>Ok</status><contractId>386010</contractId><contractTitle>kirill</contractTitle></response>

или

{"contractTitle":"kirill","contractId":386010,"status":"Ok"}

Операция contractParameters

пример запроса - /xmlWebApi/contractParameters?contractId=386010 или /jsonWebApi/contractParameters?contractId=386010

ответы:

<response><status>Ok</status><contractParameters><contractParameter><id>4</id><typeId>1</typeId><title>Ф.И.О. руководителя</title><read>true</read><write>true</write><value>Иванов Иван Иванович</value></contractParameter><contractParameter><id>7</id><typeId>1</typeId><title>Контактное лицо</title><read>false</read><write>true</write><value/></contractParameter><contractParameter><id>1</id><typeId>1</typeId><title>Краткое название организации</title><read>true</read><write>true</write><value>Фирма</value></contractParameter><contractParameter><id>20</id><typeId>3</typeId><title>e-mail</title><read>true</read><write>true</write><value>&lt;info@company.ru&gt;</value></contractParameter><contractParameter><id>40</id><typeId>9</typeId><title>Телефон (новый)</title><read>true</read><write>true</write><value>7 (347) 292-48-23</value></contractParameter></contractParameters></response>

или

{"contractParameters":[{"read":"true","typeId":"1","id":"4","title":"Ф.И.О. руководителя","write":"true","value":"Иванов Иван Иванович"},{"read":"false","typeId":"1","id":"7","title":"Контактное лицо","write":"true"},{"read":"true","typeId":"1","id":"1","title":"Краткое название организации","write":"true","value":"Фирма"},{"read":"true","typeId":"3","id":"20","title":"e-mail","write":"true","value":"&lt;info@company.ru&gt;"},{"read":"true","typeId":"9","id":"40","title":"Телефон (новый)","write":"true","value":"7 (347) 292-48-23"}],"status":"Ok"}