Пример сервиса лояльности на базе Symfony и API Platform. Сервис демонстрирует полный цикл начисления бонусов по программам лояльности на основании событий из внешнего процессинга, а также предоставляет read‑only API для просмотра программ и истории начислений.
- Приём событий из платёжного/транзакционного процессинга (
/api/bonuses/process-event, POST,ProcessEventResource). - Расчёт бонусов по активным программам лояльности в зависимости от:
- типа операции (
spend/redeem— см.CalculationFlowEnum), - параметров программы (курс, коэффициент, длительность действия бонусов —
LoyaltyProgramSettings), - валюты операции и валюты программы.
- типа операции (
- Получение списка программ лояльности и их деталей (
/api/bonuses/loyalty-programs,LoyaltyProgramResource). - Получение истории начислений бонусов (
/api/bonuses/history,BonusesHistoryResource). - Обогащённая OpenAPI‑схема и декларативные ресурсы API Platform (ресурсы находятся в
src/ApiPlatform/Resource).
LoyaltyProgram— сущность программы лояльности (мерчант, валюта бонусов, срок действия, доп. данные и т.д.).LoyaltyProgramSettings— настройки программы (ratio, converted_currency, duration и пр.) через value‑objectLoyaltyProgramSettingи enumSettingsEnum.BonusesHistory— история начисленных бонусов, включая:- информацию об операции (
OperationInfo), - сущности‑инициаторе (
EntityInfo— товар, мерчант, награда и т.п.), - детали бонусов (
BonusDetails), - состояние обратной связи (
CallbackInfo).
- информацию об операции (
Все ключевые сущности используют value‑object‑ы и трейт‑ы (Traits) для идентификаторов, статусов и коллекций, а также расширения Gedmo (soft delete, timestampable).
- Внешний процессинг вызывает
POST /api/bonuses/process-event(ProcessEventResource). - Запрос маппится в команду
ProcessEventRequestCommand(валидация через Symfony Validator). - Команда отправляется в шину сообщений (Messenger), где обрабатывается
ProcessEventRequestCommandHandler. - Хендлер, через
ProcessEventHandlerResolver, выбирает конкретный обработчик в зависимости отoperationType:SpendCalculationFlowHandlerдляspend‑сценария;RedeemCalculationFlowHandler— заглушка для сценария списания (redeem).
- В
SpendCalculationFlowHandler:- получаются активные программы лояльности для сущности (
LoyaltyProgramRepository::findActivePrograms()), - по настройкам программы считываются коэффициент и параметры конверсии,
- через
ProcessingClientзапрашивается курс валюты во внешнем процессинге, CalculationServiceрассчитывает сконвертированную сумму и количество бонусов,- создаётся сущность
BonusesHistoryс рассчитанными данными и сроком действия, - запись сохраняется через
BonusesHistoryService.
- получаются активные программы лояльности для сущности (
- Клиенту возвращается JSON с рассчитанными бонусами по каждой подходящей программе.
LoyaltyProgramResource:GET /api/bonuses/loyalty-programs— список программ с пагинацией;GET /api/bonuses/loyalty-programs/{id}— детали конкретной программы.
BonusesHistoryResource:GET /api/bonuses/history— история начислений бонусов.
Выходные модели ресурсов используют AutoMapper (MapFrom) для маппинга из доменных сущностей и группы сериализации (#[Groups]) для управления составом ответа.
- PHP 8.2+
- Symfony (HTTP‑ядро, Validator, Messenger, HttpClient и др.)
- API Platform (ресурсы, провайдеры/процессоры, OpenAPI)
- Doctrine ORM, Embeddables и Gedmo расширения (SoftDeleteable, Timestampable)
- Symfony HttpClient для интеграции с внешним процессингом (
ProcessingClient).
Проект задуман как учебный/референсный пример реализации сервиса лояльности:
- как организовать доменную модель программ лояльности и истории бонусов;
- как использовать API Platform для описания REST API и документации;
- как отделить расчётный пайплайн (
Processing+Handler‑ы +CalculationService) от HTTP‑слоя и транспорта.
Для реальной интеграции в прод окружение предполагается доработка слоёв безопасности, логирования, ретраев, обработки redeem‑сценариев и т.п.