Нюансы каналов
актуальнаяПодводные камни HTTP и TCP и особенности кассы с фискальной SAM-картой.
HTTP
- Сессия живёт активностью кассы. Сервер считает её живой, если касса опрашивала его в последние 120 секунд. Свернули приложение: через две минуты придёт
YaKassa session not FoundилиYaKassa session closed. Request already working. Сервер обрабатывает предыдущий запрос этой сессии. Подождите и повторите: параллельно слать документы в одну сессию нельзя.YaKassa session not working. Сервер 6 секунд ждал, пока касса заберёт документ. Обычно приложение свёрнуто или связь плохая.- Один «последний документ» на сессию. Статус можно спрашивать по последнему отправленному
idили по чеку, который уже есть в базе сервера. Состояние «отправил A, отправил B, спрашиваю A» вернётThe ID does not match the original request. - Заголовки
sessionID,app,verвнутренние, их шлёт сама касса. Вам они не нужны.
TCP
- Нет авторизации. Любой, кто видит порт кассы, может пробить чек. Держите кассу в изолированном сегменте и не пробрасывайте порт наружу.
- Одно соединение, один запрос. Сокет закрывается после ответа, хотя в заголовках стоит
Connection: keep-alive. Читайте ровноContent-Lengthбайт. - Разделитель строк в ответе
\n, а не\r\n. Обычные клиенты это принимают, самописный разбор должен это учесть. Content-Lengthобязателен.Transfer-Encoding: chunkedне поддерживается.Expect: 100-continueне поддерживается. curl добавляет его для тел больше 1 КБ и ждёт секунду впустую. Отключайте:-H 'Expect:'.- Таймаут чтения запроса 4 секунды. Отправляйте заголовки и тело сразу.
- Строка заголовка до 1024 байт. Более длинная закрывает соединение без ответа.
- Пути сравниваются точно. Неверный путь даёт
404. - Два формата ошибок. Транспорт и проверка документа:
{"status":"fail","message":"…"}, код HTTP 200, 400, 404 или 500. Ответы v4:{"id":…,"status":"ERROR","info":…}. Разбирайте оба. - Результаты живут в памяти. После перезапуска приложения статус по старому
idвернёт «Документ не найден». Если чек важен, проверьте его поиском, а не пробивайте вслепую. linkиprintбез запроса на TCP пусты,gnsResultприходит только в операциях со сменой.
Касса с SAM-картой
Кассы бывают двух типов, и для обмена это заметно.
| Облачная касса | Касса с SAM-картой | |
|---|---|---|
| Кто подписывает чек | сервер ОФД по запросу кассы | сама касса, картой |
| Когда сервер узнаёт о чеке | в момент фискализации | когда касса отправит подписанный документ |
- По TCP разницы нет. Результат отдаётся сразу после подписи чека картой, связь с сервером не нужна. Обмен по TCP работает и без интернета.
- По HTTP результат приходит сразу после подписи чека, а не после доставки документа в ГНС.
- Отказ ГНС на ответ по чеку не влияет. Документ создаёт карта: номер присвоен, подпись получена, чек выдан. Доставку в ГНС касса повторяет сама. Пробивать такой чек заново нельзя, получится второй фискальный документ.
OKзначит «чек фискализирован», а не «документ уже в ГНС». Состояние доставки видно на кассе и в личном кабинете ОФД, в ответе обмена его нет.- Повтор с тем же
idбезопасен. Если чек ещё не дошёл до сервера, повторныйreceipt-v4вернётDocument accepted, но касса сама отсечёт дубль. fnKKMв ответе это номер фискального модуля SAM-карты.- Смену на такой кассе открывает и закрывает сама карта.
Общее
- Возврат требует
fdNumberисходного чека, не вашid. Для возврата на карту хранитеrrnкаждой продажи, см. возвраты. - Смена. Если смена закрыта или старше суток, документ завершится ошибкой, когда автооткрытие выключено.
- QR. Поле
qrэто готовая ссылка, кодируйте её как есть, ничего не дописывая. - Своё на чеке. Реквизиты передавайте в
print, остальное вprintInfo. Протаскивать текст наименованиями товаров нельзя: они уходят в ГНС и в электронный чек.