# Распознавание счетов на оплату

Номер, дата, поставщик и покупатель с ИНН и КПП, банковские реквизиты, позиции и итог — из PDF, скана или фото. Реквизиты и сумма проверяются.

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

| Поле | Описание | Тип | Проверка |
| --- | --- | --- | --- |
| `number` | Номер счёта | string |  |
| `date` | Дата счёта | string (date) |  |
| `supplier` | Поставщик | object |  |
| `supplier.name` | Наименование | string |  |
| `supplier.inn` | ИНН | string | ИНН |
| `supplier.kpp` | КПП (у ИП нет) | string | КПП |
| `buyer` | Покупатель | object |  |
| `buyer.name` | Наименование | string |  |
| `buyer.inn` | ИНН | string | ИНН |
| `buyer.kpp` | КПП (у ИП нет) | string | КПП |
| `bank` | Банковские реквизиты поставщика | object |  |
| `bank.bik` | БИК | string | БИК |
| `bank.account` | Расчётный счёт | string | р/с по БИК |
| `bank.corr_account` | Корреспондентский счёт | string |  |
| `items[]` | Позиции | array |  |
| `items[].name` | Наименование | string |  |
| `items[].quantity` | Количество | number |  |
| `items[].unit` | Единица измерения | string |  |
| `items[].price` | Цена | number |  |
| `items[].amount` | Сумма | number |  |
| `vat_amount` | Сумма НДС (null — без НДС) | number |  |
| `total` | Итого к оплате | number | сумма строк |

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

## JSON Schema

```json
{
  "type": "object",
  "properties": {
    "number": {
      "type": "string",
      "description": "Номер счёта"
    },
    "date": {
      "type": "string",
      "format": "date",
      "description": "Дата счёта"
    },
    "supplier": {
      "type": "object",
      "description": "Поставщик",
      "properties": {
        "name": {
          "type": "string",
          "description": "Наименование"
        },
        "inn": {
          "type": "string",
          "description": "ИНН",
          "x-typizer-check": "inn"
        },
        "kpp": {
          "type": "string",
          "description": "КПП (у ИП нет)",
          "x-typizer-check": "kpp"
        }
      },
      "required": [
        "name",
        "inn",
        "kpp"
      ]
    },
    "buyer": {
      "type": "object",
      "description": "Покупатель",
      "properties": {
        "name": {
          "type": "string",
          "description": "Наименование"
        },
        "inn": {
          "type": "string",
          "description": "ИНН",
          "x-typizer-check": "inn"
        },
        "kpp": {
          "type": "string",
          "description": "КПП (у ИП нет)",
          "x-typizer-check": "kpp"
        }
      },
      "required": [
        "name",
        "inn",
        "kpp"
      ]
    },
    "bank": {
      "type": "object",
      "description": "Банковские реквизиты поставщика",
      "properties": {
        "bik": {
          "type": "string",
          "description": "БИК",
          "x-typizer-check": "bik"
        },
        "account": {
          "type": "string",
          "description": "Расчётный счёт",
          "x-typizer-check": "account"
        },
        "corr_account": {
          "type": "string",
          "description": "Корреспондентский счёт"
        }
      },
      "required": [
        "bik",
        "account",
        "corr_account"
      ]
    },
    "items": {
      "type": "array",
      "description": "Позиции",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Наименование"
          },
          "quantity": {
            "type": "number",
            "description": "Количество"
          },
          "unit": {
            "type": "string",
            "description": "Единица измерения"
          },
          "price": {
            "type": "number",
            "description": "Цена"
          },
          "amount": {
            "type": "number",
            "description": "Сумма"
          }
        },
        "required": [
          "name",
          "quantity",
          "unit",
          "price",
          "amount"
        ]
      }
    },
    "vat_amount": {
      "type": "number",
      "description": "Сумма НДС (null — без НДС)"
    },
    "total": {
      "type": "number",
      "description": "Итого к оплате",
      "x-typizer-check": "sum_of",
      "x-typizer-sum-of": "items[].amount"
    }
  },
  "required": [
    "number",
    "date",
    "supplier",
    "buyer",
    "bank",
    "items",
    "vat_amount",
    "total"
  ]
}
```

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

```json
{
  "number": "418",
  "date": "2026-09-14",
  "supplier": {
    "name": "ООО «Северный ветер»",
    "inn": "0012345673",
    "kpp": "001201001"
  },
  "buyer": {
    "name": "ИП Смирнова Анна Олеговна",
    "inn": "001234567887",
    "kpp": null
  },
  "bank": {
    "bik": "040000001",
    "account": "40702810800000000001",
    "corr_account": "30101810100000000001"
  },
  "items": [
    {
      "name": "Картридж лазерный",
      "quantity": 4,
      "unit": "шт",
      "price": 3200,
      "amount": 12800
    },
    {
      "name": "Бумага А4, 500 л.",
      "quantity": 10,
      "unit": "пач",
      "price": 410,
      "amount": 4100
    }
  ],
  "vat_amount": null,
  "total": 16900
}
```

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

- Счёт на оплату не имеет утверждённой формы: у каждого поставщика своя вёрстка, поэтому шаблоны здесь ломаются чаще всего. Typizer ищет поля по смыслу, а не по координатам.
- НДС бывает выделен построчно, одной суммой или отсутствует («Без НДС»). Поле `vat_amount` может быть null — это нормальный результат, а не ошибка.
- БИК и расчётный счёт поставщика проверяются вместе: контрольный ключ расчётного счёта считается с учётом БИК.

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

- ИНН поставщика и покупателя — контрольные цифры (10 цифр у организаций, 12 у ИП).
- КПП — формат из 9 знаков.
- БИК — формат; расчётный счёт — контрольный ключ с учётом БИК.
- Итого — сумма позиций против итоговой суммы документа.

## Вызов 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":{"number":{"type":"string","description":"Номер счёта"},"date":{"type":"string","format":"date","description":"Дата счёта"},"supplier":{"type":"object","description":"Поставщик","properties":{"name":{"type":"string","description":"Наименование"},"inn":{"type":"string","description":"ИНН","x-typizer-check":"inn"},"kpp":{"type":"string","description":"КПП (у ИП нет)","x-typizer-check":"kpp"}},"required":["name","inn","kpp"]},"buyer":{"type":"object","description":"Покупатель","properties":{"name":{"type":"string","description":"Наименование"},"inn":{"type":"string","description":"ИНН","x-typizer-check":"inn"},"kpp":{"type":"string","description":"КПП (у ИП нет)","x-typizer-check":"kpp"}},"required":["name","inn","kpp"]},"bank":{"type":"object","description":"Банковские реквизиты поставщика","properties":{"bik":{"type":"string","description":"БИК","x-typizer-check":"bik"},"account":{"type":"string","description":"Расчётный счёт","x-typizer-check":"account"},"corr_account":{"type":"string","description":"Корреспондентский счёт"}},"required":["bik","account","corr_account"]},"items":{"type":"array","description":"Позиции","items":{"type":"object","properties":{"name":{"type":"string","description":"Наименование"},"quantity":{"type":"number","description":"Количество"},"unit":{"type":"string","description":"Единица измерения"},"price":{"type":"number","description":"Цена"},"amount":{"type":"number","description":"Сумма"}},"required":["name","quantity","unit","price","amount"]}},"vat_amount":{"type":"number","description":"Сумма НДС (null — без НДС)"},"total":{"type":"number","description":"Итого к оплате","x-typizer-check":"sum_of","x-typizer-sum-of":"items[].amount"}},"required":["number","date","supplier","buyer","bank","items","vat_amount","total"]}' \
  --form-string 'instructions=Номер и дата счёта, поставщик и покупатель с ИНН и КПП, банковские реквизиты поставщика, позиции, НДС, итого'
```

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

### Что если в счёте нет КПП или НДС?

У ИП нет КПП, а при упрощённой системе нет НДС. Если их нет в документе, поле получает null и статус missing — пропуск видно сразу.

### Подойдёт ли фото счёта с телефона?

Да: JPEG, PNG, WebP и другие изображения проходят распознавание текста. Чем ровнее и резче снимок, тем меньше полей со статусом warn; для сложных снимков есть режим «Точный».

### Можно ли выгрузить счета в Excel?

Да. Пакет счетов в кабинете или через API выгружается в XLSX: одна строка на счёт, позиции — на отдельном листе со ссылкой на документ.
