Это старая версия документа!
Содержание
SERVICE_REQUEST в DONE: финализация оплаты и закрытие
Область: ShariX Open. Обработчик: open_service_request_done, тип SERVICE_REQUEST (2), статус DONE. Проверено 29.10.2026: опубликованный Python побайтово совпадает с результатом канонического renderer Blockly workspace. Реальная выбранная версия и платёжный backend установки проверяются отдельно.
Назначение и границы
Работа по заказу уже завершена. Handler повторяет платёжную финализацию и отдельно проверяет возможность перевести Ticket DONE→CLOSED. Он не просит исполнителя снова выполнить работу, не повторяет round finish, не пересчитывает фактическое окончание и не создаёт следующий повторный заказ своим processing.
DONE, успешный результат платёжного retry и разрешение закрытия — разные состояния. BPMN описательные, isExecutable=false; исполняется выбранный проверенный Python, сгенерированный из Blockly, а не схема Wiki.
Порядок вызовов (BPMN)
При своём статусе последовательно выполняются retry_done_payment и close_after_done. Boolean-результат первого вызова не используется для ветвления. Даже после обработанного retry success=false handler пробует закрытие: решающее условие проверяет отдельный gate.
Если close возвращает success=true, runtime локально устанавливает CLOSED, очищает waiting reason и исключает Ticket из очереди. Иначе записывает payment_finalization и назначает defer по SERVICE_REQUEST_DONE_PAYMENT_RETRY_SECONDS.
Исключение API/транспорта первого вызова прерывает проход, поэтому close после него в том же проходе не выполняется. Исключение второго вызова также идёт в общий processing_error. Это отличается от штатного доменного «оплата ещё не завершена», допускающего обычный повтор.
В processing нет отдельной загрузки order context и нет раунда ответа: каждый backend action самостоятельно проверяет текущий scope и заказ. При чужом локальном статусе handler запрашивает удаление из очереди и комнаты.
Backend и внешнее платёжное состояние (BPMN)
Оба action доступны через HasHandlerAPIKey, собственный capability и текущий Ticket scope. Они блокируют актуальный Orders и требуют DONE; произвольный generic ticket.transition не используется.
retry-done-payment
Требует order.retry_done_payment, вызывает handle_after_order_done через выбранный payment facade и возвращает success, payment_status и сообщение. Сам этот action не меняет стадию Ticket. Если hook отсутствует/вернул None, retry считается успешным с пояснением, что повтор не требуется.
Success здесь не является универсальным доказательством оплаченности. Неуспех также не означает, что работу надо выполнить повторно. Конкретные gateway-операции, идемпотентность внешних запросов и необходимость действия клиента принадлежат выбранному платёжному backend; из одного handler нельзя вывести гарантию нового списания на каждом проходе или обязательный внешний gateway для любой установки.
close-after-done
Требует order.close_after_done, вызывает ensure_order_can_be_closed. Если возвращённый hook имеет should_block_transition=true, backend отвечает payment_blocked и сохраняет DONE. Если блокировки нет, выполняется канонический CLOSED, к сообщению может добавиться информация платёжного hook.
Поэтому previous retry success=true не отменяет запрет gate, а retry success=false сам по себе не запрещает закрытие, если gate его допускает. Это два последовательных запроса с самостоятельной проверкой актуального DONE, а не один неизменяемый снимок и не общая атомарная транзакция runtime.
Если между запросами другой разрешённый процесс изменил статус, последующий scoped запрос может вернуть 404. Runtime очищает устаревшую локальную запись как stale; stale не доказывает, что именно этот handler выполнил CLOSED. Wrapper close считает завершением только success=true. Фактический Ticket нужно перечитать прежде, чем повторять неопределённую запись.
Что ожидается снаружи
Платёжное состояние может меняться из-за gateway, предусмотренного клиентского действия или разрешённой работы оператора в платёжном модуле. Конкретное действие нужно определять по текущему payment state/customer_action и ответу gate, а не угадывать по одному waiting reason.
Сам handler не отправляет в этом processing приглашение оплатить, не открывает клиенту интерфейс и не подтверждает получение gateway callback. Эти участники показаны на BPMN как внешний платёжный контур. Повторный проход заново обращается к backend; изменение состояния не обязано совпасть по времени с XMPP-событием Ticket.
Ожидание, ошибки и восстановление
| Назначение | Настройка |
|---|---|
| Обычный платёжный повтор после неуспешного close | SERVICE_REQUEST_DONE_PAYMENT_RETRY_SECONDS |
| Общее исключение | DEFERRED_TICKET_RECHECK_SECONDS, processing_error |
| Сверка состава очереди | INTERVAL_TIME_BD_REQ |
Defer освобождает worker; событие может сделать Ticket ready раньше. Причина payment_finalization — локальное состояние, не отдельное поле оплаченности в БД. После успешного close причина очищается. Backend commit и доставка wakeup разделены: потеря ticket.changed/ticket.moved не откатывает CLOSED, periodic reconciliation восстанавливает состав очереди.
При диагностике сначала прочитайте фактический DONE/CLOSED, затем отдельно результат retry и причину блокировки close. Auth/transport/5xx не приравнивайте к ожидаемому платёжному ожиданию. Не меняйте Ticket вручную на CLOSED лишь ради снятия очереди и не повторяйте finish, если работа уже DONE. Повтор платёжного действия после неопределённого ответа требует сверки в каноническом платёжном состоянии, а не предположения по журналу handler.
Проверенные источники
Git SHA/SHA-256 и модели закреплены в metadata/BPMN и сверены при упаковке. Handler, gateway и бизнес-API при анализе не исполнялись. Общий автоматический hook Wiki пока не завершён.
- sharix-open-handlers-examples / handlers/open_service_request_done.py — Git 76e0c693b628ed4a1fa34515a3f8abdff26149bb.
- sharix-open-handlers-examples / generated_handler_blocks/open_service_request_done.json — Git 76e0c693b628ed4a1fa34515a3f8abdff26149bb.
- sharix-open-handlers-examples / catalog.py — Git 76e0c693b628ed4a1fa34515a3f8abdff26149bb.
- sharix-open-handlers-backend / core/blockly_runtime.py — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-handlers-backend / core/requesters.py — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-handlers-backend / core/order_action_messages.py — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-handlers-backend / ticket_blockly_codegen.py — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-handlers-backend / ticket_codegen_contract.json — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-tickets / lib/tickets.py — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
- sharix-open-tickets / api/handler_auth.py — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
- sharix-open-tickets / signals.py — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
- sharix-open-tickets / services/handler_wakeup.py — Git fd64704d7d9f01a5ec5b7b89cbc5afe5102b2c14.
- sharix-open-backend / apiviews/handler_order_workflow.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / apiviews/open_api.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/order_handler_relay.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/handler_order_context.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/order_workflow_policy.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/order_actions.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/order_permissions.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / urls.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/order_lifecycle.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-backend / lib/order_provider_requirements.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.
- sharix-open-handlers-backend / core/order_rounds.py — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-handlers-backend / settings_schema.py — Git 50baf376e224d915a87d63240f3f339b3dda9afa.
- sharix-open-backend / lib/payments/facade.py — Git 778a3280cee115ba0efe3fdff7b0e708b0c10093.