Это старая версия документа!
Содержание
SERVICE_REQUEST в DONE: финализация оплаты и закрытие
Назначение: Сценарий процесса. Продукт: ShariX Open.
Для кого: Разработчик · Поддержка · Интегратор · Рецензент и приёмщик · Нейросеть.
Темы: Заказы → Финализация оплаты · Заказы → Жизненный цикл.
Область: ShariX Open. Обработчик: open_service_request_done, тип SERVICE_REQUEST (2), статус DONE. 31.10.2026 опубликованные исходники повторно получены из Git. Обе Python-копии заново сопоставлены с результатом генерации Blockly; проверены 11 исходников генераторов. Сам handler не исполнялся. Выбранную версию, конфигурацию и внешние подключения сервера проверяют отдельно.
Назначение и границы
Работа по заказу уже завершена. Handler повторяет платёжную финализацию и отдельно проверяет возможность перевести Ticket DONE→CLOSED. Он не просит исполнителя снова выполнить работу, не повторяет round finish, не пересчитывает фактическое окончание и не создаёт следующий повторный заказ своим processing.
Здесь нужно различать:
- DONE — работа по заказу завершена;
- Результат платёжного retry — ответ конкретной попытки финализации;
- Разрешение закрытия — самостоятельный gate перед DONE → CLOSED.
BPMN описательные, isExecutable=false. Runtime исполняет выбранный Python, сгенерированный из Blockly; схема Wiki процесс не запускает.
Порядок вызовов (BPMN)
В своём статусе handler выполняет:
- Вызвать
retry_done_payment. - Если первый вызов не бросил исключение — вызвать
close_after_done. - При success=true у close — завершить локальную обработку.
- При неуспешном close — сохранить payment_finalization и defer по SERVICE_REQUEST_DONE_PAYMENT_RETRY_SECONDS.
Boolean первого вызова не выбирает следующую ветвь: обработанный retry success=false не запрещает попытку close. Решающее условие проверяет отдельный backend gate.
Если close возвращает success=true, runtime локально устанавливает CLOSED, очищает waiting reason и исключает Ticket из очереди. Иначе записывает payment_finalization и назначает defer по SERVICE_REQUEST_DONE_PAYMENT_RETRY_SECONDS.
Обработанный ответ и исключение имеют разные последствия:
- Первый вызов бросил исключение: close в этом проходе не выполняется; ошибка идёт в общий processing_error.
- Второй вызов бросил исключение: общий processing_error.
- Доменный close не разрешён: обычное ожидание финализации с именованным повтором.
В 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 восстанавливает состав очереди.
Порядок диагностики:
- Прочитать фактический Ticket: DONE или CLOSED.
- Отдельно записать результат retry-done-payment.
- Прочитать ответ close-after-done и причину блокировки gate.
- Если ответ записи был неопределённым — сверить каноническое платёжное состояние до повтора.
Auth/transport/5xx не приравнивают к ожидаемому платёжному ожиданию. Не менять Ticket на CLOSED ради снятия очереди и не повторять finish уже выполненной работы.
Проверенные источники
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.