> ## Documentation Index
> Fetch the complete documentation index at: https://docs.exode.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Биллинг доступов к продуктам

> Выгрузка биллинговых записей доступов к продуктам: статусы списаний, даты продления и завершения

**type:** `QUERY_EXPORT_TYPE_PRODUCT_BILLING_ACCESS_FIND_MANY`

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

Это тип отчёта для метода [`query-export/generate`](/ru/exode-api/school/query-export/generate): передайте его
в поле `type`, а описанные ниже поля — в `variables`.

<Info>
  Отчёт строится по доступам к продуктам (`productAccessManageFindMany`) с акцентом на биллинг (подписки и
  рассрочки). `variables` — фильтр и сортировка доступов (`FilterAccessProductInput` / `SortAccessProductInput`),
  та же структура, что у отчёта [«Студенты школы»](/ru/exode-api/school/query-export/school-student-find-many).
  Неизвестные поля сервис экспорта игнорирует.
</Info>

***

### Переменные (`variables`)

<ParamField body="filter" type="object">
  Параметры фильтрации доступов (биллинговые поля — с префиксом `billing`).

  <Expandable title="Свойства filter">
    <ParamField body="userIds" type="integer[]">Фильтр по ID пользователей.</ParamField>
    <ParamField body="accessIds" type="integer[]">Фильтр по ID доступов.</ParamField>
    <ParamField body="active" type="boolean">Только активные (`true`) или деактивированные (`false`) доступы.</ParamField>
    <ParamField body="billingActive" type="boolean">Только доступы с активным биллингом (подписка/рассрочка).</ParamField>

    <ParamField body="hasProductBillingTypes" type="string[]">
      Тип биллинга. Массив из значений: `Subscription`, `Installment`.
    </ParamField>

    <ParamField body="billingStatuses" type="string[]">
      Статус биллинга. Массив из значений: `Scheduled`, `Processing`, `WaitingEntryFee`, `Paid`, `Failed`,
      `CanceledByUser`, `CanceledByFailedAutoCharge`, `CanceledByFailedManualCharge`,
      `CanceledByPreviousCancellation`, `CanceledByReinitialization`.
    </ParamField>

    <ParamField body="billingIntervals" type="string[]">
      Интервал списания. Массив из значений: `Week`, `Month`, `Year`.
    </ParamField>

    <ParamField body="billingInvoiceIds" type="integer[]">Фильтр по ID счетов биллинга.</ParamField>

    <ParamField body="billingAmountRange" type="object">
      Диапазон суммы списания. Свойства `from` и `to` — числа.
    </ParamField>

    <ParamField body="billingCurrentPaymentAtDateRange" type="object">
      Диапазон дат последнего списания. Свойства `from` и `to` — даты ISO 8601.
    </ParamField>

    <ParamField body="billingNextPaymentAtDateRange" type="object">
      Диапазон дат следующего списания. Свойства `from` и `to` — даты ISO 8601.
    </ParamField>

    <ParamField body="product" type="object">Вложенный фильтр по продукту (`productIds` и т.д.).</ParamField>
    <ParamField body="price" type="object">Вложенный фильтр по тарифу.</ParamField>
  </Expandable>
</ParamField>

<ParamField body="sort" type="object">
  Параметры сортировки. Значения: `ASC` (по возрастанию) или `DESC` (по убыванию).

  <Expandable title="Свойства sort">
    <ParamField body="id" type="string">Сортировка по ID. `ASC` | `DESC`.</ParamField>
    <ParamField body="createdAt" type="string">Сортировка по дате выдачи доступа. `ASC` | `DESC`.</ParamField>
    <ParamField body="updatedAt" type="string">Сортировка по дате обновления. `ASC` | `DESC`.</ParamField>
    <ParamField body="billingStatus" type="string">Сортировка по статусу биллинга. `ASC` | `DESC`.</ParamField>
    <ParamField body="billingPercent" type="string">Сортировка по проценту оплаты. `ASC` | `DESC`.</ParamField>
    <ParamField body="currentPaymentAt" type="string">Сортировка по дате последнего списания. `ASC` | `DESC`.</ParamField>
    <ParamField body="nextPaymentAt" type="string">Сортировка по дате следующего списания. `ASC` | `DESC`.</ParamField>
    <ParamField body="billingPaidCount" type="string">Сортировка по числу выполненных списаний. `ASC` | `DESC`.</ParamField>
  </Expandable>
</ParamField>

### Колонки отчёта

Лист **Billing Access**: ID пользователя, Фамилия Имя, Способ входа, Номер телефона, Почта, Telegram, ID платежа,
Дата последнего платежа, Дата следующего платежа, Оплачено на последнем платеже, Внесенная сумма, Общая сумма,
*Процент платежей*, *Кол-во выполненных платежей*, *Количество платежей*, *Кол-во продлений*, *Период продления*,
ID курса, Название курса, ID тарифа, Тариф, Способ оплаты, Статус.

<Info>
  Колонки *Процент платежей*, *Кол-во выполненных платежей* и *Количество платежей* появляются только при
  фильтре по рассрочке (`hasProductBillingTypes: ["Installment"]`), а *Кол-во продлений* и *Период продления* —
  только при фильтре по подписке (`hasProductBillingTypes: ["Subscription"]`).
</Info>

Дополнительный лист **Billing Details** — построчная разбивка платежей: ID пользователя, ID доступа, ID биллинга,
Номер, Дата платежа, Статус, Сумма, ID инвойса, Использованные попытки, Всего попыток, Дата следующей попытки,
Дата отмены.

<RequestExample>
  ```bash cURL theme={null}
  curl --location 'https://api.exode.biz/saas/v2/query-export/generate' \
    --header 'Seller-Id: {{ sellerId }}' \
    --header 'School-Id: {{ schoolId }}' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer YOUR_TOKEN' \
    --data '{
      "type": "QUERY_EXPORT_TYPE_PRODUCT_BILLING_ACCESS_FIND_MANY",
      "variables": {
        "filter": {
          "billingStatuses": ["Paid", "Failed"]
        },
        "sort": {
          "billingStatus": "DESC"
        }
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const axios = require('axios');

  const exportBillingAccess = async () => {
    try {
      const response = await axios.post('https://api.exode.biz/saas/v2/query-export/generate', {
        type: 'QUERY_EXPORT_TYPE_PRODUCT_BILLING_ACCESS_FIND_MANY',
        variables: {
          filter: {
            billingStatuses: ["Paid", "Failed"]
          },
          sort: {
            billingStatus: 'DESC'
          }
        }
      }, {
        headers: {
          'Seller-Id': '{{ sellerId }}',
          'School-Id': '{{ schoolId }}',
          'Content-Type': 'application/json',
          'Authorization': 'Bearer YOUR_TOKEN'
        }
      });

      const { uuid } = response.data.payload;
      console.log('Execution UUID:', uuid);
    } catch (error) {
      console.error('Error:', error.response?.data || error.message);
    }
  };

  exportBillingAccess();
  ```

  ```php PHP theme={null}
  <?php

  $url = 'https://api.exode.biz/saas/v2/query-export/generate';
  $data = [
    'type' => 'QUERY_EXPORT_TYPE_PRODUCT_BILLING_ACCESS_FIND_MANY',
    'variables' => [
      'filter' => [
        'billingStatuses' => ['Paid', 'Failed']
      ],
      'sort' => [
        'billingStatus' => 'DESC'
      ]
    ]
  ];

  $headers = [
    'Seller-Id: {{ sellerId }}',
    'School-Id: {{ schoolId }}',
    'Content-Type: application/json',
    'Authorization: Bearer YOUR_TOKEN'
  ];

  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

  $response = curl_exec($ch);
  $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);

  if ($httpCode === 200 || $httpCode === 201) {
    $result = json_decode($response, true);
    echo "Execution UUID: " . $result['payload']['uuid'] . "\n";
  } else {
    echo "Error: HTTP $httpCode\n";
    echo $response;
  }
  ?>
  ```

  ```python Python theme={null}
  import requests

  url = 'https://api.exode.biz/saas/v2/query-export/generate'

  data = {
    'type': 'QUERY_EXPORT_TYPE_PRODUCT_BILLING_ACCESS_FIND_MANY',
    'variables': {
      'filter': {
        'billingStatuses': ['Paid', 'Failed']
      },
      'sort': {
        'billingStatus': 'DESC'
      }
    }
  }

  headers = {
    'Seller-Id': '{{ sellerId }}',
    'School-Id': '{{ schoolId }}',
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_TOKEN'
  }

  try:
    response = requests.post(url, json=data, headers=headers)
    response.raise_for_status()

    result = response.json()
    print(f"Execution UUID: {result['payload']['uuid']}")

  except requests.exceptions.RequestException as e:
    print(f'Error: {e}')
  ```

  ```bsl 1С theme={null}
  Статусы = Новый Массив;
  Статусы.Добавить("Paid");
  Статусы.Добавить("Failed");

  Фильтр = Новый Структура;
  Фильтр.Вставить("billingStatuses", Статусы);

  Сортировка = Новый Структура;
  Сортировка.Вставить("billingStatus", "DESC");

  Переменные = Новый Структура;
  Переменные.Вставить("filter", Фильтр);
  Переменные.Вставить("sort", Сортировка);

  Данные = Новый Структура;
  Данные.Вставить("type", "QUERY_EXPORT_TYPE_PRODUCT_BILLING_ACCESS_FIND_MANY");
  Данные.Вставить("variables", Переменные);

  // Serialize body to JSON
  ЗаписьJSON = Новый ЗаписьJSON;
  ЗаписьJSON.УстановитьСтроку();
  ЗаписатьJSON(ЗаписьJSON, Данные);
  ТелоЗапроса = ЗаписьJSON.Закрыть();

  Соединение = Новый HTTPСоединение("api.exode.biz", 443, , , , 30, Новый OpenSSLSecureConnection);

  Запрос = Новый HTTPЗапрос("/saas/v2/query-export/generate");
  Запрос.Заголовки.Вставить("Seller-Id", "{{ sellerId }}");
  Запрос.Заголовки.Вставить("School-Id", "{{ schoolId }}");
  Запрос.Заголовки.Вставить("Content-Type", "application/json");
  Запрос.Заголовки.Вставить("Authorization", "Bearer YOUR_TOKEN");
  Запрос.УстановитьТелоИзСтроки(ТелоЗапроса);

  Ответ = Соединение.ВызватьHTTPМетод("POST", Запрос);

  Если Ответ.КодСостояния = 200 Тогда
      ЧтениеJSON = Новый ЧтениеJSON;
      ЧтениеJSON.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
      Результат = ПрочитатьJSON(ЧтениеJSON);
      Сообщить("Экспорт запущен");
  Иначе
      Сообщить("Ошибка: HTTP " + Ответ.КодСостояния);
      Сообщить(Ответ.ПолучитьТелоКакСтроку());
  КонецЕсли;
  ```
</RequestExample>

<ResponseExample>
  ```json Success theme={null}
  {
    "success": true,
    "code": 200,
    "payload": {
      "total": 100,
      "completed": 100,
      "status": "Completed",
      "result": {
        "fileUrl": "https://static.exode.biz/generated/reports/79d46a97-a149-432b-bac7-45f6732b9115.xlsx",
        "fileName": "79d46a97-a149-432b-bac7-45f6732b9115.xlsx",
        "fileSize": 6748
      }
    }
  }
  ```
</ResponseExample>

***

*Обновлено: 2026-07-22 12:24 UTC*
