Перейти к содержимому
v1
REST
Подключено к налоговой

Документация для разработчиков

Регистрируйте продажи, предоплаты и возвраты в налоговой Армении из любого стека.

Базовый URLhttps://vcr.am/api/v1

Быстрый старт

Регистрация продажи одним POST-запросом.

bash
curl https://vcr.am/api/v1/sales \
  -H "X-API-Key: $VCR_AM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "cashier": { "id": 1 },
    "items": [{
      "offer": { "externalId": "SKU-001" },
      "department": { "id": 1 },
      "quantity": "1",
      "price": "20000",
      "unit": "pc"
    }],
    "amount": { "nonCash": "20000" },
    "buyer": {
      "type": "individual",
      "receipt": { "email": "buyer@example.com", "language": "en" }
    }
  }'

Начните без налоговых реквизитов

Тестовая касса получает регистрационный номер сразу при создании — без обмена сертификатами с налоговой и без ожидания. Тот же базовый URL, те же эндпоинты, та же работа с ключом; отличаются только чеки: они помечаются TEST и никуда не подаются.

  1. 1В личном кабинете откройте «Кассы», нажмите «Создать кассу» и выберите «Тестовая касса». Создавайте столько, сколько нужно.
  2. 2Выпустите API-ключ на этой кассе. Ключ привязан к одной кассе, поэтому ключ от боевой так и будет отвечать 403.
  3. 3Вызывайте те же эндпоинты по тому же базовому URL. Когда будете готовы к реальной фискализации, создайте боевую кассу и замените ключ.

Создано для боевых интеграций

REST поверх JSON
Эндпоинты без состояния, JSON, вызов из любого языка и фреймворка.
Типизированные Node.js и PHP SDK
Типизированные клиенты на npm и Packagist — готовы к использованию на сервере как из Node.js, так и из PHP.
Аутентификация по API-ключу
Отзываемые API-ключи, которыми вы управляете из личного кабинета.
Полный API кассы
Продажи, предоплаты, возвраты и чеки — единый последовательный интерфейс.

Что должна предоставить ваша система

Перед интеграцией убедитесь, что каждая продажа несёт данные, которые требует налоговая.

Код классификатора
Код из товарного классификатора для товаров или классификатора видов деятельности — для услуг.
Единица измерения
кг, шт, м², час, услуга, работа и т.д.
Идентификатор отдела
Куда регистрировать продажу в кассе — и какой налоговый режим попадёт в чек. Необязательный: если не передать, позиция возьмёт отдел своего товара.
Идентификатор кассира
Кто регистрирует продажу.

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

Каждый запрос должен содержать ваш API-ключ в заголовке X-API-Key. Единственное исключение — GET /exchange-rate: он публичный и ключа не требует.

X-API-Key: your_api_key

Создавайте и обновляйте API-ключи в настройках вашей кассы.

Идемпотентность

Фискальный чек нельзя исправить — только вернуть и выпустить заново. Поэтому дубль здесь обходится дороже всего, а повторный вызов вебхука от платёжной системы — это норма, а не исключение. Передавайте заголовок Idempotency-Key в каждом POST: повтор того же запроса вернёт исходный чек, а не создаст второй.

Idempotency-Key: 3f6b2c1e-9a84-4d77-9f2a-1c5e0b7d8a63
Что брать в качестве ключа

UUID, сгенерированный один раз на одну фискальную операцию и сохранённый рядом с заказом до первого вызова, а затем повторяемый при каждой попытке. Не номер заказа сам по себе — один заказ может законно породить несколько фискальных документов. И не новый UUID на каждую попытку — это лишает смысла весь механизм.

Как отличить повтор от нового чека

Повторный ответ побайтово совпадает с исходным и содержит заголовок Idempotent-Replay: true. Проверяйте его, прежде чем считать ответ новым проведённым документом.

Когда вебхук может прийти дважды

У обработчика без состояния ещё ничего не сохранено, поэтому ключ нужно вычислять, а не генерировать. Тогда обе доставки получат один и тот же ключ, и вторая вернёт повтор. Не вычисляйте ключ из идентификатора события платёжной системы: другое событие по тому же заказу даст другой ключ и приведёт к повторной фискализации.

import { v5 as uuidv5 } from "uuid";

const NAMESPACE = "6f1d1a58-0d0c-4a1e-9a1a-2f9a7b3c4d5e";
const key = uuidv5(`${order.id}:sale`, NAMESPACE);

await fetch("https://vcr.am/api/v1/sales", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.VCR_API_KEY,
    "Idempotency-Key": key,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(payload),
});

Ключ остаётся повторяемым 30 дней — достаточно, чтобы месячная сверка при перезапуске вернула повтор, а не создала новый документ. Тот же ключ с другим телом запроса даёт 422; тот же ключ, пока первый запрос ещё выполняется, даёт 409 — это значит подождать и повторить с тем же ключом, а не выпускать новый. Тело, отклонённое схемой, ключ не расходует: запрос не дошёл до операции, поэтому исправьте поле и повторите с тем же ключом.

Ошибки

Ошибки возвращаются стандартными HTTP-кодами и JSON-телом с подробностями.

СтатусНазваниеКогда возникает
400
Неверный запросНеверный формат тела или ошибка валидации схемы.
401
Не авторизованAPI-ключ отсутствует или недействителен.
403
Доступ запрещёнКасса ещё не может подавать документы: нет регистрационного номера или она не активирована в налоговой.
404
Не найденоЗапрашиваемый ресурс не существует.
409
КонфликтНалоговая отклонила документ по существу, встроенная позиция конфликтует с уже существующей, или запрос с тем же Idempotency-Key ещё выполняется. При отказе приходит `pending`: документ сохранён, поэтому устраняйте причину, а не отправляйте повторно.
422
Ключ использован повторноТот же Idempotency-Key пришёл с другим телом запроса. Новому документу нужен новый ключ.
500
Внутренняя ошибкаНепредвиденный сбой на нашей стороне. Повторите с экспоненциальной задержкой.
502
Налоговая недоступнаДокумент сохранён, в ответе приходит `pending`. Сначала прочитайте `pending.mayResubmit`: false означает, что повтор создаст второй чек — вместо этого опрашивайте `pending.statusUrl`.

Что почитать дальше

Авансы и предоплаты
Модель из двух чеков, которую требует закон, когда деньги приходят раньше товара, и как потом зачесть остаток.

Продолжить разработку

Обозреватель API
Интерактивный обозреватель OpenAPI.
Node.js / TypeScript
Next.js, NestJS, Express, Bun, Deno, обычный Node.js
PHP
Symfony, WordPress, Bitrix, обычный PHP
WooCommerce
Магазин на WordPress + WooCommerce
Плагин для WooCommerce
Установить из GitHub

Скоро в каталоге плагинов WordPress.org