# Распознавание банковских выписок

Счёт, банк, период и остатки, все операции с контрагентом, ИНН, назначением платежа и суммами — из PDF или скана выписки в таблицу.

## Что извлекается

| Поле | Описание | Тип | Проверка |
| --- | --- | --- | --- |
| `account` | Номер счёта | string | р/с по БИК |
| `bik` | БИК банка | string | БИК |
| `bank` | Банк | string |  |
| `period_from` | Начало периода | string (date) |  |
| `period_to` | Конец периода | string (date) |  |
| `opening_balance` | Входящий остаток | number |  |
| `closing_balance` | Исходящий остаток | number |  |
| `operations[]` | Операции | array |  |
| `operations[].date` | Дата операции | string (date) |  |
| `operations[].doc_number` | Номер документа | string |  |
| `operations[].counterparty` | Контрагент | string |  |
| `operations[].counterparty_inn` | ИНН контрагента | string | ИНН |
| `operations[].purpose` | Назначение платежа | string |  |
| `operations[].credit` | Приход | number |  |
| `operations[].debit` | Расход | number |  |
| `total_credit` | Обороты по приходу | number | сумма строк |
| `total_debit` | Обороты по расходу | number | сумма строк |

Если значения нет в документе, поле возвращается как null со статусом missing.

## JSON Schema

```json
{
  "type": "object",
  "properties": {
    "account": {
      "type": "string",
      "description": "Номер счёта",
      "x-typizer-check": "account"
    },
    "bik": {
      "type": "string",
      "description": "БИК банка",
      "x-typizer-check": "bik"
    },
    "bank": {
      "type": "string",
      "description": "Банк"
    },
    "period_from": {
      "type": "string",
      "format": "date",
      "description": "Начало периода"
    },
    "period_to": {
      "type": "string",
      "format": "date",
      "description": "Конец периода"
    },
    "opening_balance": {
      "type": "number",
      "description": "Входящий остаток"
    },
    "closing_balance": {
      "type": "number",
      "description": "Исходящий остаток"
    },
    "operations": {
      "type": "array",
      "description": "Операции",
      "items": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "description": "Дата операции"
          },
          "doc_number": {
            "type": "string",
            "description": "Номер документа"
          },
          "counterparty": {
            "type": "string",
            "description": "Контрагент"
          },
          "counterparty_inn": {
            "type": "string",
            "description": "ИНН контрагента",
            "x-typizer-check": "inn"
          },
          "purpose": {
            "type": "string",
            "description": "Назначение платежа"
          },
          "credit": {
            "type": "number",
            "description": "Приход"
          },
          "debit": {
            "type": "number",
            "description": "Расход"
          }
        },
        "required": [
          "date",
          "doc_number",
          "counterparty",
          "counterparty_inn",
          "purpose",
          "credit",
          "debit"
        ]
      }
    },
    "total_credit": {
      "type": "number",
      "description": "Обороты по приходу",
      "x-typizer-check": "sum_of",
      "x-typizer-sum-of": "operations[].credit"
    },
    "total_debit": {
      "type": "number",
      "description": "Обороты по расходу",
      "x-typizer-check": "sum_of",
      "x-typizer-sum-of": "operations[].debit"
    }
  },
  "required": [
    "account",
    "bik",
    "bank",
    "period_from",
    "period_to",
    "opening_balance",
    "closing_balance",
    "operations",
    "total_credit",
    "total_debit"
  ]
}
```

## Пример результата (данные вымышлены)

```json
{
  "account": "40702810000000000002",
  "bik": "040000002",
  "bank": "АО «Условный банк»",
  "period_from": "2026-09-01",
  "period_to": "2026-09-30",
  "opening_balance": 152340.5,
  "closing_balance": 248940.5,
  "operations": [
    {
      "date": "2026-09-03",
      "doc_number": "311",
      "counterparty": "ООО «Клиент Один»",
      "counterparty_inn": "0012312318",
      "purpose": "Оплата по счёту № 418 от 14.09.2026, без НДС",
      "credit": 120000,
      "debit": null
    },
    {
      "date": "2026-09-15",
      "doc_number": "87",
      "counterparty": "ООО «Аренда Офисов»",
      "counterparty_inn": "0045645640",
      "purpose": "Аренда за сентябрь 2026 г.",
      "credit": null,
      "debit": 23400
    }
  ],
  "total_credit": 120000,
  "total_debit": 23400
}
```

## Особенности документа

- Выписки разных банков свёрстаны по-разному, а операции занимают десятки страниц. Typizer собирает операции со всех страниц в один массив, у каждой строки — источник с номером страницы.
- Назначение платежа — свободный текст; из него удобно отдельными полями достать, например, номер счёта или договора, если описать это в схеме.
- Для сверки остатков добавьте в схему обороты: сумма операций по дебету и кредиту сверяется с итоговыми оборотами выписки.

## Что проверяет Typizer

- БИК — формат; номер счёта — контрольный ключ с учётом БИК.
- ИНН контрагентов — контрольные цифры.
- Обороты — сумма операций против итоговых оборотов выписки.

## Вызов API

Инструкция: Номер счёта, банк и БИК, период, входящий и исходящий остаток, обороты, операции: дата, номер документа, контрагент и его ИНН, назначение, приход, расход

```bash
curl -X POST 'https://api.typizer.ru/v1/extract?wait=60' \
  -H 'Authorization: Bearer tz_live_YOUR_API_KEY' \
  -H "Idempotency-Key: $(uuidgen)" \
  -F 'file=@document.pdf' \
  --form-string 'schema={"type":"object","properties":{"account":{"type":"string","description":"Номер счёта","x-typizer-check":"account"},"bik":{"type":"string","description":"БИК банка","x-typizer-check":"bik"},"bank":{"type":"string","description":"Банк"},"period_from":{"type":"string","format":"date","description":"Начало периода"},"period_to":{"type":"string","format":"date","description":"Конец периода"},"opening_balance":{"type":"number","description":"Входящий остаток"},"closing_balance":{"type":"number","description":"Исходящий остаток"},"operations":{"type":"array","description":"Операции","items":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"Дата операции"},"doc_number":{"type":"string","description":"Номер документа"},"counterparty":{"type":"string","description":"Контрагент"},"counterparty_inn":{"type":"string","description":"ИНН контрагента","x-typizer-check":"inn"},"purpose":{"type":"string","description":"Назначение платежа"},"credit":{"type":"number","description":"Приход"},"debit":{"type":"number","description":"Расход"}},"required":["date","doc_number","counterparty","counterparty_inn","purpose","credit","debit"]}},"total_credit":{"type":"number","description":"Обороты по приходу","x-typizer-check":"sum_of","x-typizer-sum-of":"operations[].credit"},"total_debit":{"type":"number","description":"Обороты по расходу","x-typizer-check":"sum_of","x-typizer-sum-of":"operations[].debit"}},"required":["account","bik","bank","period_from","period_to","opening_balance","closing_balance","operations","total_credit","total_debit"]}' \
  --form-string 'instructions=Номер счёта, банк и БИК, период, входящий и исходящий остаток, обороты, операции: дата, номер документа, контрагент и его ИНН, назначение, приход, расход'
```

## Вопросы и ответы

### Выписка на 40 страниц — это 40 страниц тарифа?

Да, для PDF и изображений страница — это физическая страница документа. Выписку из интернет-банка в XLSX или CSV распознавать обычно не нужно.

### Можно ли разнести операции по статьям?

Добавьте в схему поле категории с перечнем значений (enum) и описанием правил — модель выберет категорию для каждой операции. Источник покажет, из какого текста она выведена.

### Безопасно ли загружать выписки?

Обработка идёт в России, данные не используются для обучения моделей, а исходник можно удалять сразу после прогона — это настройка организации.
