cheque — Windows-ориентированный Python-проект для работы с кассовым оборудованием и связанными платёжными сценариями.
README рассчитан на двух читателей:
- разработчика, который сопровождает проект;
- будущего Codex-агента, которому нужно быстро понять структуру, точки входа и ограничения окружения.
Основной поток проекта:
- чтение JSON с составом чека;
- подготовка и печать чека через ККТ Штрих;
- обработка оплат и возвратов по эквайрингу;
- обработка оплат и возвратов по СБП;
- проверка кодов маркировки;
- запись служебных данных и логов.
Проект завязан на локальное окружение кассы и внешние устройства. Это не универсальная библиотека, а прикладной набор скриптов для конкретной инфраструктуры Windows.
Главная точка входа для печати чека.
Что делает:
- читает входные данные чека;
- создаёт объект ККТ;
- при необходимости проверяет маркировку;
- запускает оплату через
pinpad_tbank.pyилиpinpad_OOP.py; - запускает оплату или возврат через СБП;
- печатает служебные блоки оплаты;
- закрывает чек;
- сохраняет данные для последующей выгрузки.
Ожидает аргументы командной строки:
python .\check.py <path_to_receipt_dir> <receipt_name_without_json>Скрипт использует файл:
<path_to_receipt_dir>\<receipt_name_without_json>.json
Отдельный служебный сценарий для операций ККТ и печати сопутствующих отчётов.
Поддерживает, по коду, как минимум:
x_otchetz_otchetz_otchet_onlyrepeataboutopen_box
Также умеет печатать данные по СБП и пинпаду, если это указано во входном JSON.
Запуск:
python .\operation_shtrih.py <path_to_receipt_dir> <receipt_name_without_json>Интеграция с терминалом Т-Банка через DualConnector и вспомогательный PosGui.
Особенности текущей реализации:
- конфигурация терминалов хранится в
tbank.ini; - общие таймауты и параметры
PosGuiтакже читаются изtbank.ini; - таймаут обмена с терминалом возвращается как код ошибки
2000; - используется отдельная логика GUI-диалогов для ручного взаимодействия с кассиром.
Интеграция со сбербанковским пинпадом через COM-объект SBRFSRV.Server.
Что делает:
- выполняет оплату
sale; - выполняет возврат
return_sale; - умеет запускать сверку итогов
reconciliation; - умеет запускать отчётные операции
x_otchet,z_otchet,full_otchet; - возвращает код результата терминала в
error; - возвращает текст слипа или чека в
text.
Как используется в проекте:
- в
check.pyвыбирается, еслиpinpad_typeне равен"tbank"; - в
operation_shtrih.pyиспользуется для служебных операций и печати отчётов по пинпаду.
То есть это не запасной файл, а рабочая интеграция для сценариев эквайринга Сбербанка.
shtrih_OOP.py— работа с ККТ Штрих;SBP_OOP.py— СБП Сбербанк;alfabank_SBP.py— СБП через Альфа-Банк;pinpad_OOP.py— сбербанк сценарий пинпада;receipt_db.py— локальная БД чеков;dbf_make.py— формирование DBF;preparation_km_to_honest_sign.py— подготовка данных маркировки;logger_config.py— конфигурация логирования;my_rec.py— пример структуры входного чека.
Проект рассчитан на Windows.
По коду видно жёсткую привязку к локальным путям и окружению, например:
d:\kassa\script_py\shtrih\d:\kassa\db_receipt\D:\files\- локальные
.env-файлы и сертификаты
Также ожидается наличие:
- установленного Python;
- доступа к COM/драйверам оборудования;
- кассового ПО и драйверов Штрих;
- сетевой доступности внешних банковских и терминальных сервисов;
- файлов сертификатов и ключей, которые не должны попадать в репозиторий.
Зависимости перечислены в requirements.txt.
Установка:
python -m venv .venv
.\.venv\Scripts\activate
pip install -r .\requirements.txtКлючевые используемые библиотеки:
python-decouplepython-dotenvrequestsrequests-pkcs12PySimpleGUI-4-fosspywin32pyserialqrcodePyAutoGUI
В проекте используется локальный .env, который читают разные модули, в том числе:
check.pySBP_OOP.pyalfabank_SBP.py
Точный состав переменных зависит от используемого сценария. По коду точно видно, что в конфигурации могут использоваться:
- параметры минидисплея, например
lcd_com; - банковские URL и идентификаторы;
- пути к локальным БД;
- сервисные учётные данные и сертификаты.
Секреты, ключи и реальные значения в README не дублируются.
lcd_com— COM-порт минидисплея, используется вcheck.py
Используются в SBP_OOP.py:
clientSecretclientIDtidmemberidsert_passsert_name
Используются в alfabank_SBP.py:
private_key_pathalfa_aliasalfa_tls_crtalfa_tls_keyalfa_sbp_urlalfa_sql_path
Также используются кассир-зависимые ключи:
alfa_temno_kassir1alfa_qrcid_kassir1alfa_temno_kassir2alfa_qrcid_kassir2alfa_temno_kassir3alfa_qrcid_kassir3alfa_temno_kassir11alfa_qrcid_kassir11
По коду имя ключа строится динамически:
alfa_temno_<windows_username>
alfa_qrcid_<windows_username>
Если Windows-пользователь называется иначе, в .env должны существовать соответствующие пары ключей именно под его имя.
Часть интеграций может ожидать дополнительные переменные в связанных внешних модулях или локальном окружении кассы. README фиксирует только то, что явно читается из текущего кода репозитория.
Конфигурация T-Банка вынесена в отдельный INI-файл.
Структура:
[kassir1]
url=http://...
tid=...
[kassir11]
url=http://...
tid=...
posgui_addr=127.0.0.1:6000
[timeout]
operation_timeout_seconds=10
currency_code=643
posgui_addr=127.0.0.1:6000
posgui_codepage=windows-1251
posgui_connect_timeout_seconds=1.0
posgui_response_timeout_padding_seconds=5.0
posgui_enabled=1
posgui_required=0
posgui_manual_dialogs=1
posgui_result_dialog_timeout_seconds=3Смысл секций:
- секции вида
[kassirN]описывают конкретные терминалы или кассы; - секция
[timeout]хранит общие настройки времени ожидания иPosGui.
Входные данные подаются через JSON-файл чека.
Пример структуры можно посмотреть в my_rec.py.
По текущему коду важны, как минимум, такие поля:
operationtypeitemssum-cashsum-cashlesssumm3PinPadpinpad_typeSBPSBP-typenumber_receiptinitial_sale_numberinitial_sale_datetag1021emailperm_mode
Ниже не полный, а рабочий сокращённый пример структуры, собранный по my_rec.py и check.py:
{
"id": "EL5532/02",
"number_receipt": "5532/02",
"date_create": "20260210",
"operationtype": "sale",
"tax-type": 1,
"tag1021": "Кассир",
"tag1203": "644917946302",
"email": "",
"perm_mode": 1,
"PinPad": 0,
"pinpad_type": "tbank",
"SBP": 1,
"SBP-type": "sber",
"sum-cash": 0.0,
"sum-cashless": 0.0,
"summ3": 1267.0,
"summ4": 0.0,
"sum": 1267.0,
"initial_sale_number": "",
"initial_sale_date": "10.02.26",
"cutter": "~S",
"text-basement": [""],
"items": [
{
"name": "Товар 1",
"id": "1",
"nn": "2310648306135",
"seller": "П341|Кассир",
"department": "",
"comment": "",
"artname": "Товар 1",
"artnom": "310648",
"katname": "Категория",
"katnom": "61",
"nds": "20",
"gtd": "",
"country": "*",
"marktip": "5408",
"barcode": "0104...",
"quantity": 1,
"price": 499.0,
"fullprice": 499.0,
"discount": 0.0,
"taxtype": 1,
"paymenttypesign": 4,
"bonuswritedown": 0,
"bonusaccrual": 25,
"qr": "0104...",
"qr_water": "",
"paymentitemsign": 33
}
],
"km": [
"0104..."
],
"km_water": [],
"bonusi": [
"Бонусов будет начислено: 63"
],
"bonus_items": [],
"rn": "0009347016042401",
"fn": "7384440900773851",
"reqId": "8066e45b-1b88-4346-a664-55c379d3f3a5",
"reqTimestamp": 1770729524199
}Что важно:
itemsдолжны содержать позиции чека в формате, который понимаетshtrih_OOP.py;- поля
SBP,PinPad,summ3,sum-cashlessуправляют платёжными сценариями; - для возврата используются
operationtype = "return_sale",initial_sale_numberиinitial_sale_date; - если включена проверка маркировки, должны быть корректно заполнены
items[*].qr,items[*].marktipи списокkm.
Проект пишет логи в файловую систему Windows.
По текущему коду используются, в частности:
D:\files\— основные логи;d:\kassa\db_receipt\— локальные БД и служебные данные;- текстовые и промежуточные файлы рядом со сценариями кассы.
Если каталогов нет или права доступа ограничены, часть сценариев не запустится.
- Проект сильно зависит от конкретной инфраструктуры и путей.
- В коде есть прямые
os.chdir(...)в рабочий каталог кассы. - Логика рассчитана на запуск рядом с драйверами, JSON-файлами чеков и локальными БД.
- Часть модулей взаимодействует с внешним оборудованием и не может быть полноценно протестирована без стенда.
Минимальная проверка синтаксиса:
python -m py_compile .\check.py .\operation_shtrih.py .\pinpad_tbank.pyЗапуск основного сценария:
python .\check.py <path_to_receipt_dir> <receipt_name_without_json>Запуск служебных операций ККТ:
python .\operation_shtrih.py <path_to_receipt_dir> <receipt_name_without_json>Ниже перечислены коды, которые явно видны в текущем коде проекта.
0— сценарий завершился успешно96— ошибка инициализации или выполнения сценария СБП98— не пройдена проверка маркировки99— неизвестный тип операции9888— не удалось импортировать модуль проверки маркировки9992— не удалось импортироватьpinpad_tbank.Tbank9993— не удалось импортироватьreceipt_db.Receiptinsql9994— не удалось импортироватьalfabank_SBP.Alfa_SBP9995— не удалось импортироватьSBP_OOP.SBP9997— не удалось импортироватьpinpad_OOP.PinPad9998— не удалось импортировать модуль или класс Штрих
0— операция терминала завершилась успешно2000— пользовательская отмена или таймаут ожидания терминала97— ответ терминала не удалось интерпретировать однозначно
Для pinpad_tbank.py это именно внутренние коды клиента, которые потом поднимаются наружу в check.py.
0— штатное завершение служебной операции
Остальные ошибки в этом сценарии, как правило, идут через исключение или драйвер ККТ, а не через отдельную таблицу кодов возврата.
В проекте есть и другие коды ошибок на уровне драйверов ККТ, банковских API и COM-интеграций. README фиксирует только те коды, которые явно управляются логикой самих Python-скриптов.
Минимальная идея входного JSON:
operationtype = "sale"PinPad = 1pinpad_type = "tbank"sum-cashless > 0SBP = 0
Запуск:
python .\check.py d:\path\to\receipts EL5532_02Что произойдёт:
check.pyпрочитаетEL5532_02.json;- создаст объект ККТ;
- вызовет
pinpad_tbank.py; - дождётся результата терминала;
- напечатает служебный слип оплаты;
- закроет чек и завершится с кодом
0либо с кодом ошибки пинпада.
Минимальная идея входного JSON:
operationtype = "sale"SBP = 1SBP-type = "sber"илиSBP-type = "alfabank_bank"summ3 > 0PinPad = 0
Запуск:
python .\check.py d:\path\to\receipts EL5532_02Что произойдёт:
- при
SBP-type = "sber"будет использованSBP_OOP.py; - при любом другом значении сейчас уходит ветка в
alfabank_SBP.py; - скрипт создаст заказ на оплату;
- дождётся подтверждения оплаты или отмены;
- напечатает информацию по СБП;
- затем закроет чек.
Минимальная идея входного JSON:
operationtype = "return_sale"SBP = 1summ3 > 0initial_sale_numberзаполненinitial_sale_dateзаполнен
Запуск:
python .\check.py d:\path\to\receipts EL5532_02Что произойдёт:
- будет найдена исходная операция оплаты;
- по данным исходной продажи сформируется возврат;
- результат возврата будет распечатан в чеке.
Во входном JSON достаточно указать:
operationtype = "x_otchet"илиoperationtype = "z_otchet"
Запуск:
python .\operation_shtrih.py d:\path\to\receipts service_receiptЧто произойдёт:
- будет открыт сценарий служебной операции ККТ;
- напечатается X- или Z-отчёт;
- данные о кассе могут быть дополнительно сохранены в текстовый файл.
pinpad_tbank.py можно запускать отдельно как ручной тестовый клиент.
Примеры:
python .\pinpad_tbank.py payment --amount 1.00 --section kassir1
python .\pinpad_tbank.py refund --amount 1.00 --section kassir1
python .\pinpad_tbank.py short_report --section kassir1
python .\pinpad_tbank.py posgui_info --section kassir1Это полезно, когда нужно проверить терминал, PosGui или tbank.ini отдельно от полного кассового сценария.
- убрать жёстко зашитые пути в конфигурацию;
- формализовать схему входного JSON;
- отделить слой интеграций с оборудованием от сценарной логики;
- сократить количество побочных эффектов при импорте модулей;
- добавить отдельный документ с обязательными переменными
.envдля каждого платёжного сценария.