API

СмИТ Биллинг 1.0 предоставляет несколько типов API для интеграции с внешними системами: платёжными шлюзами, личными кабинетами, 1С, системами мониторинга и другими сервисами.

Базовый URL: https://your-billing-server.example.com
Авторизация: Cookie-сессия (Django) или SOAP-хэш
Формат данных: JSON (REST), XML (SOAP)

Обзор API

ТипПротоколURLАутентификация
REST API v2JSON over HTTP/rest_api/v2/<model>/Cookie (session)
REST API v1JSON/XML/rest_api/Cookie (session)
SOAP APIXML (Spyne)/api/, /api/fiscal/SOAP-хэш
System APIJSON/system_api/IP whitelist + пароль
Web Admin APIHTML/JSON/admin/*Cookie + CSRF

Аутентификация

Логин через Web (получение сессии)

Двухшаговый процесс: получение CSRF-токена, затем POST с логином и паролем.

# Шаг 1: получить CSRF-токен
curl -s -c cookies.txt "https://billing.example.com/admin/" > /dev/null

# Шаг 2: логин
CSRF=$(grep csrftoken cookies.txt | awk '{print $NF}')
curl -s -c cookies.txt -b cookies.txt \
  -X POST "https://billing.example.com/admin/" \
  -d "username=admin&password=YOUR_PASSWORD&csrfmiddlewaretoken=$CSRF" \
  -H "Referer: https://billing.example.com/admin/" \
  -o /dev/null -w "%{http_code}"
# 302 = успешный вход

API-логин (JSON)

Альтернативный способ — получение сессионного хэша через GET-параметры:

curl -s "https://billing.example.com/admin/?api=1&username=admin&password=YOUR_PASSWORD&format=json"
# Ответ: {"hash": "session_hash_hex"}
# 401 = неверные учётные данные

Логаут

# Web-логаут
curl -s -b cookies.txt "https://billing.example.com/admin/logout"

# API-логаут
curl -s -b cookies.txt -X POST "https://billing.example.com/rest_api/logout"
# Ответ: {"status": "ok"}

REST API v2

Универсальный CRUD-интерфейс для работы с любой моделью биллинга. Поддерживает фильтрацию, сортировку, пагинацию и выбор полей.

Список записей

# Получить список абонентов (первые 100)
curl -s -b cookies.txt \
  "https://billing.example.com/rest_api/v2/Abonents/?limit=100&offset=0"

Ответ:

{
  "count": 5554,
  "next": "/rest_api/v2/Abonents/?limit=100&offset=100",
  "previous": null,
  "results": [
    {
      "id": 1,
      "name": "Иванов Иван Иванович",
      "contract_number": "12345",
      "email": "ivanov@example.com",
      "enabled": true,
      ...
    },
    ...
  ]
}

Фильтрация

# Абоненты с тарифом ID=131, только активные
curl -s -b cookies.txt \
  "https://billing.example.com/rest_api/v2/Abonents/?tarif=131&enabled=true"

# Поиск по имени (частичное совпадение)
curl -s -b cookies.txt \
  "https://billing.example.com/rest_api/v2/Abonents/?name__icontains=иванов"

Сортировка

# Сортировка по имени (А→Я)
curl -s -b cookies.txt \
  "https://billing.example.com/rest_api/v2/Abonents/?ordering=name"

# Обратная сортировка по балансу (от большего к меньшему)
curl -s -b cookies.txt \
  "https://billing.example.com/rest_api/v2/Abonents/?ordering=-account__ostatok"

Выбор полей

# Вернуть только id, name и contract_number
curl -s -b cookies.txt \
  "https://billing.example.com/rest_api/v2/Abonents/?fields=id,name,contract_number"

Получение одной записи

curl -s -b cookies.txt \
  "https://billing.example.com/rest_api/v2/Abonents/5552/"

Создание записи (POST)

curl -s -b cookies.txt -X POST \
  "https://billing.example.com/rest_api/v2/Abonents/" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Новый абонент",
    "contract_number": "99999",
    "email": "new@example.com",
    "tarif": 131
  }'
# Ответ: 201 Created + JSON объекта

Обновление записи (PUT)

curl -s -b cookies.txt -X PUT \
  "https://billing.example.com/rest_api/v2/Abonents/5552/" \
  -H "Content-Type: application/json" \
  -d '{"email": "updated@example.com"}'
# Ответ: 200 OK + обновлённый JSON

Удаление записи (DELETE)

curl -s -b cookies.txt -X DELETE \
  "https://billing.example.com/rest_api/v2/Abonents/5552/"
# Ответ: 204 No Content

Доступные модели

МодельОписание
AbonentsАбоненты
TarifТарифные планы
UslugaУслуги
UsersУчётные записи (логин/пароль/IP)
NasСерверы доступа (NAS/BRAS)
SwitchКоммутаторы
HomesАдреса (дерево: город→улица→дом)
IpPullIP-пулы
FinanceOperationsФинансовые операции
AdminAccountsЛицевые счета
HdskЗаявки HelpDesk
CardsКарты оплаты

Обещанный платёж

Специализированный эндпоинт для управления обещанными платежами абонентов.

GET — Статус обещанного платежа

curl -s -b cookies.txt \
  "https://billing.example.com/rest_api/v2/promise_pay/5552/"

Ответ:

{
  "abonent_id": 5552,
  "abonent_name": "Иванов Иван Иванович",
  "promise_pay": "90.00",
  "promise_date_end": "2026-03-15T12:00:00",
  "active_promises": [
    {
      "id": 3,
      "usluga_id": -4,
      "type": "prepay",
      "limit": "90.00",
      "end_time": "2026-03-15T12:00:00",
      "comment": "Обещанный платёж по предоплате до ...",
      "create_date": "2026-03-12T12:00:00"
    }
  ]
}

POST — Добавить обещанный платёж

# С параметрами по умолчанию (сумма и срок из настроек)
curl -s -b cookies.txt -X POST \
  "https://billing.example.com/rest_api/v2/promise_pay/5552/" \
  -H "Content-Type: application/json" \
  -d '{}'

# С явными параметрами
curl -s -b cookies.txt -X POST \
  "https://billing.example.com/rest_api/v2/promise_pay/5552/" \
  -H "Content-Type: application/json" \
  -d '{"limit": 500, "end_time": "2026-03-31", "postpay": false}'
ПараметрТипПо умолчаниюОписание
limitnumber90Сумма обещанного платежа (руб.)
end_timestring+3 дняДата окончания (YYYY-MM-DD или ISO 8601)
postpayboolfalsetrue = постоплата, false = предоплата

Ответ (201 Created):

{
  "status": "ok",
  "promise_id": 3,
  "abonent_id": 5552,
  "usluga_id": -4,
  "type": "prepay",
  "limit": "90",
  "end_time": "2026-03-15T12:00:00"
}

DELETE — Удалить обещанный платёж

# Удалить предоплату (по умолчанию)
curl -s -b cookies.txt -X DELETE \
  "https://billing.example.com/rest_api/v2/promise_pay/5552/"

# Удалить постоплату
curl -s -b cookies.txt -X DELETE \
  "https://billing.example.com/rest_api/v2/promise_pay/5552/?postpay=1"

Ответ (200):

{"status": "ok", "abonent_id": 5552, "message": "Promise pay deleted"}
Настройки по умолчанию хранятся в таблице Usluga:
ID -4 (предоплата): сумма 90 руб., срок 3 дня
ID -3 (постоплата): сумма 90 руб., срок 3 дня

SOAP API

SOAP-интерфейс на базе фреймворка Spyne. Используется для интеграции с платёжными системами, 1С и кассовым ПО.

WSDL

# Получить WSDL-описание сервисов
curl -s "https://billing.example.com/api/?wsdl"
curl -s "https://billing.example.com/api/fiscal/?wsdl"

Эндпоинты

URLСервисМетоды
/api/UserServiceget_user_hash
/api/v2/UserServiceget_user_hash
/api/1c/UserServiceget_user_hash
/api/userside/UserServiceget_user_hash
/api/collector/UserServiceget_user_hash
/api/cabinet/UserServiceget_user_hash
/api/fiscal/FiscalServicepay_usr_act2, pay_usr_act_import

get_user_hash — Аутентификация

curl -s -X POST "https://billing.example.com/api/" \
  -H "Content-Type: text/xml" \
  -d '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:tns="billing.users">
  <soapenv:Body>
    <tns:get_user_hash>
      <tns:username>admin</tns:username>
      <tns:hash>sha1_hex_hash</tns:hash>
    </tns:get_user_hash>
  </soapenv:Body>
</soapenv:Envelope>'
ПараметрТипОписание
usernameStringИмя пользователя
hashStringSHA1(MD5(password) + salt)

Ответ: {hash: "32-byte-hex-session-token"} — токен для SSO, хранится 1 час.

pay_usr_act2 — Проведение платежа

curl -s -X POST "https://billing.example.com/api/fiscal/" \
  -H "Content-Type: text/xml" \
  -d '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:tns="rpc.view.fiscal">
  <soapenv:Body>
    <tns:pay_usr_act2>
      <tns:hash_key>session_token</tns:hash_key>
      <tns:ACT>PAY</tns:ACT>
      <tns:CONTRACT_NUMBER>12345</tns:CONTRACT_NUMBER>
      <tns:SUM_IN>100.00</tns:SUM_IN>
      <tns:PAY_OPERATOR>Sberbank</tns:PAY_OPERATOR>
      <tns:COMMENT_IN>Оплата услуг</tns:COMMENT_IN>
    </tns:pay_usr_act2>
  </soapenv:Body>
</soapenv:Envelope>'
ПараметрТипОбязательныйОписание
hash_keyStringДаСессионный токен (из get_user_hash)
ACTStringДаТип операции: PAY, CHECK
CONTRACT_NUMBERStringДаНомер договора абонента
SUM_INStringДаСумма платежа
PAY_OPERATORStringДаНазвание оператора/платёжной системы
COMMENT_INStringНетКомментарий к платежу
PAY_ID_STRStringНетВнешний ID платежа

Web API (управление абонентами)

Эндпоинты для управления абонентами через HTTP POST. Требуют авторизацию (cookie) и CSRF-токен. Возвращают HTTP 302 (redirect) при успехе.

Блокировка абонента

CSRF=$(grep csrftoken cookies.txt | awk '{print $NF}')
curl -s -b cookies.txt -X POST \
  "https://billing.example.com/admin/abonents/block/5552/" \
  -d "csrfmiddlewaretoken=$CSRF" \
  -H "Referer: https://billing.example.com/admin/Abonents/5552/" \
  -o /dev/null -w "%{http_code}"
# 302 = успех

Разблокировка абонента

curl -s -b cookies.txt -X POST \
  "https://billing.example.com/admin/abonents/unblock/5552/" \
  -d "csrfmiddlewaretoken=$CSRF" \
  -H "Referer: https://billing.example.com/admin/Abonents/5552/"

Отключение / Восстановление

# Отключить абонента
curl -s -b cookies.txt -X POST \
  "https://billing.example.com/admin/abonents/reconnect/5552/" \
  -d "csrfmiddlewaretoken=$CSRF" \
  -H "Referer: https://billing.example.com/admin/Abonents/5552/"

# Восстановить удалённого абонента
curl -s -b cookies.txt -X POST \
  "https://billing.example.com/admin/Abonents/restore/5552/" \
  -d "csrfmiddlewaretoken=$CSRF" \
  -H "Referer: https://billing.example.com/admin/Abonents/5552/"

AJAX-эндпоинты

JSON-эндпоинты для асинхронных запросов из веб-интерфейса. Требуют авторизацию (cookie).

Получить IP из пула

# Из любого свободного пула
curl -s -b cookies.txt "https://billing.example.com/admin/ajax/ippull_get/"

# Из конкретного пула (ID=1)
curl -s -b cookies.txt "https://billing.example.com/admin/ajax/ippull_get/1/"

Ответ: {"msg": "ok", "ip": "10.0.0.5", "mask": "255.255.255.0"}

Информация о MAC-адресе

curl -s -b cookies.txt \
  "https://billing.example.com/admin/ajax/user_getinfo/?user_id=123&cmd=GetMac"

Ответ: {"msg": "ok", "mac": "AA:BB:CC:DD:EE:FF"}

Порты коммутатора

curl -s -b cookies.txt \
  "https://billing.example.com/admin/ajax/user_get_switch_port_list/?user_id=123&switch_id=1"

Ответ: [{"pk": 1, "name": "Port 1", "selected": false}, ...]

Утилиты

МетодURLОписание
GET/admin/Abonents/get_bills/<filename>Скачать файл счёта
GET/admin/Abonents/download_operations/Скачать отчёт по операциям
GET/admin/getpdf/<abonent_id>/<item_id>/Генерация PDF-документа
GET/admin/Users/resolve_dns/<ip>/Обратный DNS-запрос

Коды ошибок

HTTP-кодОписание
200Успех
201Создано (POST)
204Удалено (DELETE)
302Редирект (Web API — успех)
400Неверный запрос (ошибка валидации)
401Не авторизован
403Доступ запрещён (CSRF, READ_ONLY_MODE)
404Объект не найден
500Внутренняя ошибка сервера
READ_ONLY_MODE: Если в настройках биллинга включён режим «Только чтение» (VpnConst.READ_ONLY_MODE), все POST/PUT/DELETE запросы вернут 403 Forbidden.