8. Работа с чеками 54-ФЗ

Источник: https://docs.paykeeper.ru/dokumentatsiya-json-api/rabota-s-chekami-54-fz/

PayKeeper поддерживает автоматическую генерацию чеков по 54-ФЗ.

Список запросов

#URIНазначение
8.1/info/receipts/bydate/Реестр чеков за период с фильтрами
8.2/info/receipts/bydatecount/Счёт чеков за период по типам
8.3/info/receipts/bypaymentid/Чеки по платежу
8.4/info/receipts/byid/Чек по внутреннему номеру
8.5/info/receipts/search/Поиск чеков по фискальным атрибутам
8.6RESERVEDзарезервировано
8.7RESERVEDзарезервировано
8.8/info/itemcode/check/Проверка кода маркировки в Честном Знаке
8.9RESERVEDзарезервировано
8.10RESERVEDзарезервировано
8.11/change/receipt/print/Печать чека по платежу или произвольным атрибутам
8.12RESERVEDпроверка статуса чека у кассы
8.13CallbackОповещение при переходе чека в финальный статус

8.1 Реестр чеков /info/receipts/bydate/

Тип: GET
Формат: /info/receipts/bydate/?start=2021-01-28&end=2021-02-28&sum_type[0]=sum_cashless&sum_type[1]=sum_cash&status[0]=created&status[1]=success

Параметры запроса:

#ПараметрНазначение
1startОпц. Начало периода (YYYY-MM-DD)
2endОпц. Конец периода (YYYY-MM-DD)
3statusОпц. Массив. Фильтр по статусу (created, request_sent, success, failed, timeout)
4receipt_typeОбяз. Массив. Фильтр по типу (sale, refund, correction)
5sum_typeОбяз. Массив. Фильтр по способу оплаты (sum_cashless, sum_cash, sum_advance, sum_credit)
6sortОпц. По умолчанию request_datetime. Поле сортировки: payment_id, refund_id, request_datetime, obtain_datetime, status
7directionОпц. ASC / DESC. По умолчанию DESC
8fromОпц. По умолчанию 0
9limitОпц. По умолчанию 10

Поля массива receipts:

#ПараметрНазначение
1idID чека
2payment_idНомер платежа (может быть пустым)
3typesale / refund
4is_post_saleЧек окончательного расчёта
5refund_idПорядковый номер возврата
6statuscreated, request_sent, success, timeout, failed
7contactEmail/телефон плательщика
8sum_cashlessБезнал
9sum_cashНаличные
10sum_advanceЗачёт аванса
11sum_creditКредит
12cartКорзина (JSON-строка)
13receipt_propertiesДоп. свойства (JSON-строка)
14fpdФПД
15fndНомер ФД
16fnНомер ФН
17tsВремя формирования (YYYYMMDDTHHmm)
18rnkktРегистрационный номер ККТ
19shift_numberНомер смены
20receipt_numberНомер чека в смене
21obtain_datetimeДата оплаты
22request_datetimeДата оповещения магазина
23fop_receipt_keyКлюч чека (часть URL страницы)
24fop_uuidУникальный ID запроса к кассе
25fop_urlСодержимое QR-кода

Счётчики counts:

ПараметрНазначение
statusЧисло чеков по статусу
receipt_typeЧисло по типу
sum_typeЧисло по способу оплаты
page_sizeВсего найдено на странице
totals.sum_typeГруппировка по способу
totals.statusГруппировка по статусу
totals.receipt_typeГруппировка по типу
totals.totalВсего по запросу без пагинации

Пример ответа:

{
  "receipts": [
    {
      "id": "2107145011",
      "payment_id": "0",
      "type": "sale",
      "is_post_sale": "0",
      "refund_id": "0",
      "status": "request_sent",
      "contact": "",
      "sum_cashless": "1.00",
      "sum_cash": "0.00",
      "sum_advance": "0.00",
      "sum_credit": "0.00",
      "cart": "[{\"item_type\":\"goods\",\"payment_type\":\"prepay\",\"sku\":\"\",\"name\":\"Lorem ipsum\",\"price\":\"1\",\"quantity\":\"1\",\"item_code\":\"\",\"tax\":\"none\",\"sum\":1,\"agent\":{\"type\":\"other\"},\"supplier\":{\"phones\":[\"+79101234567\"],\"inn\":\"5544332219\",\"name\":\"ООО ТЕСТ\"}}]",
      "receipt_properties": "{\"client\":null,\"agent\":{\"type\":\"other\"},\"supplier\":{\"phones\":[\"+79101234567\"],\"inn\":\"5544332219\",\"name\":\"ООО ТЕСТ\"}}",
      "fpd": null,
      "fnd": null,
      "fn": null,
      "ts": null,
      "rnkkt": null,
      "shift_number": null,
      "receipt_number": null,
      "request_datetime": "2021-10-12 11:27:12",
      "obtain_datetime": null,
      "fop_receipt_key": "XjtaLpCw_kqfiiI",
      "fop_uuid": "27e80723-21e7-418b-9806-00f1a7e6aef8",
      "fop_url": null
    }
  ],
  "counts": {
    "status": {"request_sent": 4},
    "receipt_type": {"sale": 4},
    "sum_type": {"sum_cashless": 4},
    "page_size": 4,
    "totals": {
      "sum_type": {"sum_cashless": 4, "sum_cash": 0, "sum_advance": 0, "sum_credit": 0},
      "status": {"created": 0, "request_sent": 4, "success": 0, "failed": 0, "timeout": 0},
      "receipt_type": {"sale": 4, "refund": 0, "expense": 0, "expense_refund": 0, "correction": 0},
      "total": 4
    }
  }
}

8.2 Количество чеков /info/receipts/bydatecount/

Тип: GET
Формат: /info/receipts/bydatecount/?start=2020-10-18&end=2021-10-18

Параметры: start, end.

Пример:

{
  "sum_type": {"sum_cashless": 15, "sum_cash": 0, "sum_advance": 5, "sum_credit": 0},
  "status": {"created": 1, "request_sent": 11, "success": 7, "failed": 1, "timeout": 0},
  "receipt_type": {"sale": 20, "refund": 0, "expense": 0, "expense_refund": 0, "correction": 0},
  "total": 20
}

8.3 Чеки по платежу /info/receipts/bypaymentid/

Тип: GET
Формат: /info/receipts/bypaymentid/?payment_id=2211

Параметры: payment_id.

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


8.4 Чек по ID /info/receipts/byid/

Тип: GET
Формат: /info/receipts/byid/?id=4201

Параметры: id.

Параметры ответа:

#ПараметрНазначение
1idID чека
2payment_idНомер платежа
3typesale / refund / expense / expense-refund
4is_post_saleПризнак окончательного расчёта ("0"/"1")
5is_correctionЧек коррекции по ФФД 1.2 ("0"/"1")
6refund_idПорядковый номер возврата
7statuscreated, sending, rejected, request_sent, success, timeout, failed
8contactEmail/телефон
9sum_cashlessБезнал
10sum_cashНаличные
11sum_advanceЗачёт аванса
12sum_creditКредит
13sum_counter_paymentВстречное предоставление
14cartКорзина (JSON-строка)
15receipt_propertiesДоп. свойства (JSON-строка)
16fpdФПД
17fndНомер ФД
18fnНомер ФН
19tsВремя формирования
20rnkktРегистрационный номер
21shift_numberСмена
22receipt_numberНомер в смене
23obtain_datetimeДата оплаты
24request_datetimeДата запроса
25fop_receipt_keyКлюч чека
26fop_uuidУникальный ID запроса
27fop_urlQR-контент
28custom_paramsJSON с доп. атрибутами (для коррекции)
29errorJSON с описанием ошибки (если rejected/failed)

Статусы чеков

СтатусОписаниеФинальный
createdПринят, ожидает отправкиНет
sendingОтправляется балансировщикуНет
rejectedОтклонён балансировщиком (детали в error)Да
request_sentПринят балансировщиком, будет отправлен кассеНет
successЧек сформированДа
timeoutДолго в очереди без результата, удалёнДа
failedКасса отклонила (детали в error)Да

Поля custom_params (ФФД 1.2 коррекция)

ПолеНазначение
correction_typeself / by_order
correction_operation_dateДата исходной операции (YYYY-MM-DD, тег 1178)
correction_document_numberНомер предписания ФНС (тег 1179, до 32 симв.)

Поле error

ПолеНазначение
typesyntax_error, ffd_error, item_code_error, print_error, queue_error
messageОписание
error_idID события в логе

Типы ошибок

ТипОписание
syntax_errorСинтаксическая ошибка в запросе, отбраковка до передачи в ФН
ffd_errorЗапрещённые по ФФД теги или их комбинация, отбраковка при передаче в ФН
item_code_errorКод «Честного знака» не прошёл проверку; устройство настроено отклонять такие чеки
print_errorОбщая ошибка при обработке на ККТ
queue_errorОшибка постановки в очередь до передачи ККТ

Пример ответа:

{
  "id": "4201",
  "payment_id": "2098",
  "type": "sale",
  "is_post_sale": "1",
  "is_correction": "1",
  "refund_id": null,
  "status": "success",
  "contact": "client@mail.ru",
  "sum_cashless": "0.00",
  "sum_cash": "0.00",
  "sum_advance": "15529.10",
  "sum_credit": "0.00",
  "sum_counter_payment": "0.00",
  "cart": "[{\"name\":\"TEST 3\",\"quantity\":1,\"price\":15529.10,\"sum\":15529.10,\"tax\":\"none\",\"payment_type\":\"full\"}]",
  "receipt_properties": "null",
  "fpd": "2020473855",
  "fnd": "8930",
  "fn": "9999078900001341",
  "ts": "20190621T1638",
  "rnkkt": "0000000400054952",
  "shift_number": "7123",
  "receipt_number": "6162",
  "obtain_datetime": "2019-05-11 09:12:22",
  "request_datetime": "2019-05-11 09:12:01",
  "fop_receipt_key": "VhamK7kl",
  "fop_uuid": "6ee-cs-130",
  "fop_url": "t=20190511T0912&s=15529.10&fn=9999078900001341&i=8930&fp=2020473855&n=1",
  "custom_params": "{\"correction_type\":\"self\",\"correction_operation_date\":\"2022-04-11\"}",
  "error": null
}

8.5 Поиск чеков /info/receipts/search/

Тип: GET
Формат: /info/receipts/search/?start=2020-10-18&end=2021-10-18&query=12345

Параметры:

ПараметрНазначение
startНачало (YYYY-MM-DD)
endКонец (YYYY-MM-DD)
queryПодстрока (ищется в id, payment_id, contact)

Формат ответа как в 8.1.


8.6 / 8.7 / 8.9 / 8.10 RESERVED

Не используется.


8.8 Проверка кода маркировки /info/itemcode/check

Для режима разрешений валидация допустимости продажи товара при добавлении кода маркировки. Результат добавляется к чеку.

Тип: GET
Формат: /info/itemcode/check

Параметры:

ПараметрНазначение
item_codeКод маркировки без GS-символов (эвристика по позициям байтов)
item_code_b64Точное значение кода с GS-символами, base64

Передаётся один из двух. Если оба — используется item_code_b64.


8.11 Печать чека /change/receipt/print/

Тип: POST
Формат: /change/receipt/print/

Печать асинхронная — отправить запрос и проверять результат позже (рекомендуется через 2+ минуты).

Параметры:

#ПараметрНазначение
1payment_idНомер платежа (может быть пустой строкой ''). Обязателен
2typesale / refund / expense / expense-refund
3is_post_saleПризнак окончательного расчёта (true/false). Не отправляется для type=refund
4is_correctionЧек коррекции ФФД 1.2 (true/false)
5refund_idПорядковый номер возврата (можно '')
6contactEmail или телефон (+79101234567)
7sum_cashlessБезнал
8sum_cashНаличные
9sum_advanceАванс
10sum_creditКредит
11sum_counter_paymentВстречное предоставление
12cartКорзина (JSON-строка)
13receipt_propertiesДоп. свойства (JSON-объект)
14receipt_keyУникальный ключ (минимум 6 симв.)

Ответ:

{"receipt_id": 816}

Поля для чека коррекции (ФФД 1.2)

Дополнительные поля при is_correction=true:

ПолеНазначение
correction_typeself / by_order
correction_operation_dateДата исходной операции (YYYY-MM-DD, тег 1178)
correction_document_numberНомер предписания ФНС (тег 1179, до 32 симв.)
additional_receipt_dataНомер исправляемого чека (тег 1192)

8.12 RESERVED

Не используется. Планируется: проверка статуса чека у кассы и получение фискальных атрибутов, если они отсутствуют.


8.13 Callback о финальном статусе чека

При достижении чеком финального статуса (см. 8.4) PayKeeper шлёт POST-оповещение на сайт ТСП один раз, без подтверждения доставки.

Тело содержит все параметры из ответа 8.4 + подпись:

  • sign — цифровая подпись запроса

Вычисление подписи

Все параметры (включая пустые) сортируются по ключу лексикографически, значения конкатенируются через ;. Берётся HMAC-SHA256 с секретным словом в качестве ключа.

Проверка на PHP

<?php
  $request = $_POST;
  $pk_key = "Secret client key";
  unset($request['sign']);
  ksort($request);
  $to_hash = implode(';', $request);
  $sign = hash_hmac('sha256', $to_hash, $pk_key);
  if(strtoupper($sign) == strtoupper($_POST['sign']))
  {
   // подпись валидна
  }
?>