Go to file
2024-08-26 21:11:11 +07:00
.github/workflows init structure 2024-08-13 17:38:40 +07:00
src fix TimerProperties 2024-08-26 21:11:11 +07:00
.gitignore init structure 2024-08-13 17:38:40 +07:00
pom.xml fix TimerProperties 2024-08-26 21:11:11 +07:00
README.md IMP-268: impl service (#2) 2024-08-26 15:31:48 +03:00

disputes-api

Технические особенности

Сервисы разделены по модулям, к которым относится данный функционал, будь то ../api/, ../security/ или ../schedule/

Поэтому возможны смежные названия сервисов (как **AttachmentsService) , но при этом сервисы работают для разных задач, ограниченные рамками модулей

Реализовывать отдельное оповещение нет необходимости, потому что закладываемся, что мерчант настроит получение вебхуков по ивенту корректировки и webhook-dispatcher сам узнает об этом ивенте о пошлет уведомление

Модуль API

Модуль внешнего доступа для создания диспутов и опроса статуса. Все действия проходят через БД, проактивного запроса к провайдерскому API не происходит. Создание диспута означает лишь создание записи в БД, решение далее принимается на уровне модуля ../schedule/

При ошибках сервис кидает:

  • 5хх, если это отказ внешних шлюзов
  • 404, если это отсутствие данных
  • 400, если это ошибка в данных запросов
  • 401, если это отсутствие прав для доступа к API

При опросе диспута существует несколько значений параметра ErrorReason, при которых информация об диспуте не отдается и наружу выкидывается 404. Такое поведение возникнет, если в другом потоке шедулатора при обработке диспута возникли ошибки\отказ внешних шлюзов с ключевыми данными и в рамках данного диспута проблема является непреодолимой. Единственным способом решить данную проблему будет создание нового диспута.

Модуль Schedule

Модуль с шедулаторами, которые по расписанию обрабатывают диспуты.
Все процессы в шедулаторах проходят в изоляциях транзакций, при исключениях возникает откат.

При обработке диспутов шедулатор блочит используемые айдишники на уровне запроса к базе.
Диспут у провайдера не будет создан, пока платеж находится в не финальном статусе, это ограничение на уровне hellgate. Когда статус платежа становится captured|cancelled|failed разрешена дальнейшая обработка диспута.

(реализации на данный момент нет) Если при финальном статусе платежа captured создавать на провайдере диспут является негативной не желательной ситуацией, можно предусмотреть опцию в терминале DISPUTE_FLOW_BAN_ON_CAPTURED и пулять состояние в в топик\тг-провайдер-бот на ручной разбор

(реализации на данный момент нет) Не все провайдеры на данный момент поддерживают работу с диспутами по API.
Предполагается такой способ действия при этой ситуации:

  1. При наличии диспутов по API у провайдеров в терминале добавляется опция — DISPUTE_FLOW_PROVIDER_API_EXIST
  2. если эта опция терминала есть, то сервис ищет роут до адаптера и отправляет запрос по трифт протоколу, иначе будет пулять в топик\тг-провайдер-бот
  3. если возникнет ошибка роута, то будет пулять в топик\тг-провайдер-бот

Используется экспоненциальный пуллинг, после которого мы считаем, что диспут протух и поллить его не надо. Опция DISPUTE_FLOW_MAX_TIME_POLLING_MIN контролирует максимальное время пуллинга
Диспуты на проверку статуса упорядочиваются по последнему времени проверки поля next_check_after, берутся самые древние

Ответственность за актуальный статус диспута несет конкретный адаптер. Решение остается за адаптером, тк детали реализации могут отличаться в зависимости от интеграции, disputes-api работает уже с результатом этого процесса и занимается обновлением статуса диспута в своей БД. При этом, при создании диспута необходимо в адаптере по возможности проверять наличие существующего диспута, в случае отказа внешних шлюзов после вызова ручки создания диспута на адаптере.

Если по какой то причине на этапе опроса статуса шедулатор не найдет в БД актуальную запись об конкретном provider_dispute_id (т.е. диспут в адаптере не был создан), то обработка диспута будет возвращена на этап назад, для попытки создать диспут в адаптере заново.

Перед созданием корректировки сервис пытается найти уже созданные корректировки и найти среди них существующую корректировку и при успехе переводит диспут в успех. Этот процесс ликвидирует ситуацию дублей корректировок.
В идеале, после создания корректировки диспут переводится в успех.

Консистентность

Данная реализация предусматривает, что сервис при обработке не зависнет в неопределенном состоянии, а если это произойдет, то это не повлияет на состояние данных

Критичные внешние шлююзы:

  • postgres [RW] (хранение данных по диспутам)
  • hellgate [RW] (запись корректировок)
  • file-storage-v2 [RW] (хранение файлов чеков диспутов)
  • dominant [R] bouncer [R] token-keeper-v2 [R] (авторизация по токену)

В модуле API при падении внешних узлов в общей цепочке вызовов будет откат транзакции, данные в БД не запишутся, диспут не будет создан и наружу вернется выбранный http-код

В модуле Schedule при падении внешних узлов в общей цепочке вызовов будет откат транзакции, данные в БД не запишутся, а также продусмотрена проверка hellgate , существует ли уже такая корректировка

Запись file-storage-v2 не регулируется на уровня транзакции сервиса, но конкретно в случае file-storage-v2 возможность повторной записи не является критичным фактором

Вызов адаптеров — пулинг на падения не влияет, но при создании предполагается, что это ответственность адаптера удостовериться, что такого диспута еще не существует.