openapi: "3.0.0"
info:
  version: "2.0.0"
  title: "Система управления заправками (АЗС)"
  description: |
    Полное API для интеграции с системами управления автозаправочными станциями.
    Включает функционал для работы со справочниками АЗС, управления заправками,
    расчетом стоимости и мониторингом статуса операций.
    
    **Основные возможности:**
    - Получение списка АЗС партнера
    - Проверка состояния колонок и пистолетов
    - Расчет стоимости заправки с учетом скидок
    - Активация отпуска топлива после оплаты
    - Мониторинг статуса заправки и получение фактических итогов

servers:
  - url: http://fuel-system.local/api
    description: "Внешняя система управления АЗС"

tags:
  - name: infrastructure
    description: "Информация об АЗС и компаниях"
  - name: fueling
    description: "Управление заправками"

paths:
  /external/partners/{externalPartnerId}/stations:
    get:
      summary: "Получить список АЗС по внешнему идентификатору партнера"
      description: |
        Возвращает список автозаправочных станций, принадлежащих указанному партнеру.
        Используется для синхронизации справочника АЗС в платежной системе.
      operationId: getStationsByExternalPartner
      tags:
        - infrastructure
      parameters:
        - name: externalPartnerId
          in: path
          required: true
          description: "Внешний идентификатор партнера (компании)"
          schema:
            type: string
            minLength: 1
            maxLength: 100
          example: "partner-azs-12345"
        - name: status
          in: query
          required: false
          description: "Статус АЗС для фильтрации"
          schema:
            type: string
            enum:
              - ACTIVE
              - INACTIVE
              - MAINTENANCE
              - ALL
            default: ACTIVE
          example: ACTIVE
      responses:
        200:
          description: "Успешный ответ со списком АЗС"
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/StationExternal'
        400:
          description: "Неверные параметры запроса"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        404:
          description: "Партнер не найден"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        500:
          description: "Внутренняя ошибка сервера"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /stations/{externalStationId}/pumps/{pump}:
    get:
      summary: "Инициализация заправки"
      description: |
        Проверяет состояние колонки, определяет снятый пистолет и возвращает информацию о топливе.
        Выполняет поиск карты лояльности клиента по номеру телефона или номеру карты лояльности.
      tags:
        - fueling
      operationId: checkPumpAndLoyalty
      parameters:
        - name: externalStationId
          in: path
          required: true
          description: "Внешний идентификатор АЗС"
          schema:
            type: string
            example: "STATION_001"
        - name: pump
          in: path
          required: true
          description: "Номер ТРК (колонки)"
          schema:
            type: integer
            example: 1
        - name: phoneNumber
          in: query
          required: false
          description: "Номер телефона клиента для поиска карты лояльности"
          schema:
            type: string
            example: "+79161234567"
        - name: loyaltyCardNumber
          in: query
          required: false
          description: "Номер карты лояльности для поиска в системе"
          schema:
            type: string
            maxLength: 200
            example: "LOYALTY123456"
      responses:
        200:
          description: "Успешный ответ со статусом пистолета"
          content:
            application/json:
              schema:
                type: object
                properties:
                  pump:
                    type: integer
                    description: "Номер ТРК (колонки)"
                    example: 1
                  nozzle:
                    type: integer
                    description: "Номер пистолета"
                    example: 3
                  fuel:
                    type: string
                    description: "Наименование услуги (топлива)"
                    example: "АИ-95"
                  fuelType:
                    type: string
                    description: "Тип топлива"
                    enum: ["AI-76", "AI-80", "AI-92", "AI-95", "AI-98", "DT", "GAS", "ADBLUE"]
                    example: "AI-95"
                  price:
                    type: number
                    format: float
                    description: "Цена за единицу измерения"
                    example: 55.80
                  unit:
                    type: string
                    description: "Код единицы измерения"
                    enum: ["L", "M3"]
                    example: "L"
                    x-enum-descriptions:
                      L: "Литры"
                      M3: "Метры кубические"
                  currency:
                    type: string
                    description: "Код валюты по ISO 4217"
                    example: "933"
                  loyaltyCard:
                    type: object
                    description: "Данные карты лояльности (если найдена)"
                    properties:
                      cardNumber:
                        type: string
                        description: "Номер карты лояльности"
                        example: "LOYALTY123456"
                      bonus:
                        type: number
                        format: float
                        description: "Количество бонусных баллов"
                        example: 500.00
                      discount:
                        type: number
                        format: float
                        description: "Величина скидки в процентах"
                        example: 3.5
                      state:
                        type: string
                        description: "Статус карты"
                        enum: ["ACTIVE", "CLOSED"]
                        example: "ACTIVE"
                      default:
                        type: boolean
                        description: "Карта по-умолчанию"
                        example: true
                    required:
                      - cardNumber
                  providerMessage:
                    type: string
                    description: "Информационное сообщение от оператора"
                    example: "Заберите Ваш бесплатный кофе"
                required:
                  - pump
                  - nozzle
                  - fuel
                  - fuelType
                  - price
        400:
          description: "Колонка занята"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        404:
          description: "Колонка не найдена"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        500:
          description: "Внутренняя ошибка системы"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

    post:
      summary: "Согласовать стоимость топлива и применение скидки"
      description: |
        Рассчитывает стоимость заправки с учетом скидок и бонусов.
        Расчет зависит от algorithmCalc: 0 - расчет по количеству (dose), 1 - расчет по сумме (amount).
      tags:
        - fueling
      operationId: calculateFuelCost
      parameters:
        - name: externalStationId
          in: path
          required: true
          description: "Внешний идентификатор АЗС"
          schema:
            type: string
            example: "STATION_001"
        - name: pump
          in: path
          required: true
          description: "Номер ТРК (колонки)"
          schema:
            type: integer
            example: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                nozzle:
                  type: integer
                  description: "Номер пистолета"
                  minimum: 1
                  example: 3
                algorithmCalc:
                  type: integer
                  description: "Алгоритм расчета"
                  enum: [0, 1]
                  example: 1
                amount:
                  type: number
                  format: float
                  description: "Сумма для заправки (если algorithmCalc=1)"
                  minimum: 0
                  exclusiveMinimum: true
                  example: 1000.00
                dose:
                  type: number
                  format: float
                  description: "Количество топлива (если algorithmCalc=0)"
                  minimum: 0
                  exclusiveMinimum: true
                  example: 20.5
                bonus:
                  type: number
                  format: float
                  description: "Количество бонусных баллов для списания"
                  minimum: 0
                  example: 50.00
                loyaltyCardNumber:
                  type: string
                  description: "Номер карты лояльности"
                  maxLength: 200
                  example: "LOYALTY123456"
              required:
                - nozzle
                - algorithmCalc
              oneOf:
                - required: ["amount"]
                - required: ["dose"]
      responses:
        200:
          description: "Успешный расчет стоимости"
          content:
            application/json:
              schema:
                type: object
                properties:
                  pump:
                    type: integer
                    description: "Номер ТРК (колонки)"
                    example: 1
                  nozzle:
                    type: integer
                    description: "Номер пистолета"
                    example: 3
                  algorithmCalc:
                    type: integer
                    description: "Алгоритм расчета"
                    enum: [0, 1]
                    example: 1
                  amount:
                    type: number
                    format: float
                    description: "Сумма с учетом скидки"
                    example: 950.00
                  dose:
                    type: number
                    format: float
                    description: "Количество топлива с учетом скидки"
                    example: 17.02
                  price:
                    type: number
                    format: float
                    description: "Цена за единицу измерения"
                    example: 55.80
                  fuel:
                    type: string
                    description: "Наименование услуги (топлива)"
                    example: "АИ-95"
                  fuelType:
                    type: string
                    description: "Тип топлива"
                    enum: ["AI-76", "AI-80", "AI-92", "AI-95", "AI-98", "DT", "GAS", "ADBLUE"]
                    example: "AI-95"
                  unit:
                    type: string
                    description: "Код единицы измерения"
                    enum: ["L", "M3"]
                    example: "L"
                    x-enum-descriptions:
                      L: "Литры"
                      M3: "Метры кубические"
                  currency:
                    type: string
                    description: "Код валюты по ISO 4217"
                    example: "933"
                  discount:
                    type: number
                    format: float
                    description: "Сумма скидки"
                    example: 50.00
                  bonus:
                    type: number
                    format: float
                    description: "Количество бонусных баллов, используемых для заправки"
                    example: 50.00
                  loyaltyCard:
                    type: object
                    description: "Данные карты лояльности, которая была применена при расчете"
                    properties:
                      cardNumber:
                        type: string
                        description: "Номер карты лояльности"
                        example: "LOYALTY123456"
                    required:
                      - cardNumber
                  providerMessage:
                    type: string
                    description: "Информационное сообщение от оператора"
                    example: "Заберите Ваш бесплатный кофе"
                required:
                  - pump
                  - nozzle
                  - algorithmCalc
                  - amount
                  - dose
                  - price
                  - fuel
                  - fuelType
        400:
          description: "Неверный запрос"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        404:
          description: "Колонка не найдена"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        409:
          description: "Конфликт расчета"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        500:
          description: "Внутренняя ошибка системы"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /stations/{externalStationId}/pumps/{pump}/sale:
    post:
      summary: "Отпуск топлива (продажа)"
      description: |
        Активирует отпуск топлива (продажу) после успешного списания средств с пользователя.
        Передает команду на старт подачи топлива на указанной колонке.
      tags:
        - fueling
      operationId: startFuelSale
      parameters:
        - name: externalStationId
          in: path
          required: true
          description: "Внешний идентификатор АЗС"
          schema:
            type: string
            example: "STATION_001"
        - name: pump
          in: path
          required: true
          description: "Номер ТРК (колонки)"
          schema:
            type: integer
            example: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                nozzle:
                  type: integer
                  description: "Номер пистолета"
                  minimum: 1
                  example: 3
                algorithmCalc:
                  type: integer
                  description: "Алгоритм расчета"
                  enum: [0, 1]
                  example: 1
                amount:
                  type: number
                  format: float
                  description: "Сумма с учетом скидки"
                  minimum: 0
                  exclusiveMinimum: true
                  example: 950.00
                dose:
                  type: number
                  format: float
                  description: "Количество топлива"
                  minimum: 0
                  exclusiveMinimum: true
                  example: 17.02
                price:
                  type: number
                  format: float
                  description: "Цена за единицу измерения"
                  minimum: 0
                  exclusiveMinimum: true
                  example: 55.80
                fuel:
                  type: string
                  description: "Наименование услуги (топлива)"
                  example: "АИ-95"
                fuelType:
                  type: string
                  description: "Тип топлива"
                  enum: ["AI-76", "AI-80", "AI-92", "AI-95", "AI-98", "DT", "GAS", "ADBLUE"]
                  example: "AI-95"
                unit:
                  type: string
                  description: "Код единицы измерения"
                  enum: ["L", "M3"]
                  example: "L"
                  x-enum-descriptions:
                    L: "Литры"
                    M3: "Метры кубические"
                discount:
                  type: number
                  format: float
                  description: "Сумма скидки"
                  minimum: 0
                  example: 50.00
                loyalCardNumber:
                  type: string
                  description: "Номер карты лояльности"
                  maxLength: 200
                  example: "LOYALTY123456"
                bonus:
                  type: number
                  format: float
                  description: "Количество бонусных баллов для списания"
                  minimum: 0
                  example: 50.00
                paymentDetails:
                  type: object
                  description: "Информация о проведенной операции оплаты"
                  properties:
                    maskedCardNumber:
                      type: string
                      description: "Маскированный номер карты/кошелька"
                      example: "**** **** **** 1234"
                    operationId:
                      type: string
                      description: "Идентификатор операции оплаты в платежной системе"
                      example: "trx_123456789"
                  required:
                    - maskedCardNumber
                    - operationId
              required:
                - nozzle
                - algorithmCalc
                - amount
                - dose
                - price
                - fuel
                - discount
                - paymentDetails
      responses:
        200:
          description: "Отпуск топлива успешно активирован"
          content:
            application/json:
              schema:
                type: object
                properties:
                  saleId:
                    type: integer
                    format: int64
                    description: "Идентификатор операции (продажи) в системе АЗС. Используется для идентификации транзакции заправки во внешней системе управления АЗС."
                    example: 789012
                  pump:
                    type: integer
                    description: "Номер ТРК (колонки)"
                    example: 1
                  nozzle:
                    type: integer
                    description: "Номер пистолета"
                    example: 3
                  algorithmCalc:
                    type: integer
                    description: "Алгоритм расчета"
                    enum: [0, 1]
                    example: 1
                  amount:
                    type: number
                    format: float
                    description: "Сумма с учетом скидки"
                    example: 950.00
                  dose:
                    type: number
                    format: float
                    description: "Количество топлива"
                    example: 17.02
                  price:
                    type: number
                    format: float
                    description: "Цена за единицу измерения"
                    example: 55.80
                  fuel:
                    type: string
                    description: "Наименование услуги (топлива)"
                    example: "АИ-95"
                  fuelType:
                    type: string
                    description: "Тип топлива"
                    enum: ["AI-76", "AI-80", "AI-92", "AI-95", "AI-98", "DT", "GAS", "ADBLUE"]
                    example: "AI-95"
                  unit:
                    type: string
                    description: "Код единицы измерения"
                    enum: ["L", "M3"]
                    example: "L"
                    x-enum-descriptions:
                      L: "Литры"
                      M3: "Метры кубические"
                  discount:
                    type: number
                    format: float
                    description: "Сумма скидки"
                    example: 50.00
                  loyalCardNumber:
                    type: string
                    description: "Номер карты лояльности"
                    example: "LOYALTY123456"
                  bonus:
                    type: number
                    format: float
                    description: "Количество списанных бонусных баллов"
                    example: 50.00
                  status:
                    type: string
                    description: "Статус отпуска топлива"
                    enum: ["ACTIVATED", "IN_PROGRESS", "COMPLETED", "FAILED"]
                    example: "ACTIVATED"
                  activationTime:
                    type: string
                    format: date-time
                    description: "Время активации отпуска топлива"
                    example: "2024-12-03T12:00:00Z"
                  providerMessage:
                    type: string
                    description: "Информационное сообщение от оператора"
                    example: "Заберите Ваш бесплатный кофе"
                required:
                  - saleId
                  - pump
                  - nozzle
                  - algorithmCalc
                  - amount
                  - dose
                  - price
                  - fuel
                  - discount
                  - status
                  - activationTime
        400:
          description: "Неверный запрос"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        404:
          description: "Колонка не найдена"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        409:
          description: "Конфликт активации"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        500:
          description: "Внутренняя ошибка системы"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

  /stations/{externalStationId}/sales/{paymentId}/status:
    get:
      summary: "Мониторинг и завершение"
      description: |
        Запрос предназначен для мониторинга статуса заправки и получения фактических итоговых данных.
        
        **Основное назначение:**
        - Запрос вызывается после успешного ответа на запрос отпуска топлива (продажи)
        - Выполняется периодический опрос состояния заправки до получения окончательного статуса
        - При получении конечного успешного статуса система сравнивает предварительную сумму заправки с фактической суммой из ответа
        - В случае расхождения сумм система выполняет возврат средств на разницу сумм
        
        **Жизненный цикл статуса:**
        1. NOT_STARTED - заправка еще не началась после активации
        2. IN_PROGRESS - заправка выполняется в данный момент
        3. COMPLETED - заправка успешно завершена, доступны фактические данные
        4. CANCELLED - заправка отменена
        5. FAILED - заправка завершилась с ошибкой
        
        **Обязательные данные:**
        - status - всегда присутствует и указывает текущее состояние заправки
        - operationId - идентификатор операции в платежной системе для связи транзакций
        
        **Фактические данные (только при COMPLETED статусе):**
        - sum - фактическая сумма операции (может отличаться от предварительной)
        - sumDiscount - фактическая сумма скидки
        - amount - фактическое количество отпущенного топлива
        - checkNumber - номер фискального чека
        - priceDiscount - цена с учетом скидки
      tags:
        - fueling
      operationId: getSaleStatus
      parameters:
        - name: externalStationId
          in: path
          required: true
          description: "Внешний идентификатор АЗС"
          schema:
            type: string
            example: "STATION_001"
        - name: paymentId
          in: path
          required: true
          description: "Идентификатор операции (продажи) в системе АЗС"
          schema:
            type: integer
            format: int64
            example: 789012
      responses:
        200:
          description: "Успешный ответ со статусом и итогами заправки"
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: "Статус заправки"
                    enum: ["NOT_STARTED", "IN_PROGRESS", "COMPLETED", "CANCELLED", "FAILED"]
                    example: "COMPLETED"
                    x-enum-descriptions:
                      NOT_STARTED: "Заправка не началась"
                      IN_PROGRESS: "Заправка в процессе"
                      COMPLETED: "Заправка завершена"
                      CANCELLED: "Заправка отменена"
                      FAILED: "Заправка завершилась с ошибкой"
                  operationId:
                    type: string
                    description: "Уникальный номер операции платежной системы"
                    example: "trx_123456789"
                  sum:
                    type: number
                    format: float
                    description: "Фактическая сумма операции"
                    minimum: 0
                    example: 950.00
                  sumDiscount:
                    type: number
                    format: float
                    description: "Фактическая сумма скидки"
                    minimum: 0
                    example: 50.00
                  amount:
                    type: number
                    format: float
                    description: "Фактическое количество отпущенного топлива"
                    minimum: 0
                    example: 17.02
                  checkNumber:
                    type: string
                    description: "Номер чека"
                    example: "CHK-789012"
                  priceDiscount:
                    type: number
                    format: float
                    description: "Цена со скидкой"
                    minimum: 0
                    example: 55.80
                required:
                  - status
                  - operationId
        404:
          description: "Операция не найдена"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        500:
          description: "Внутренняя ошибка системы"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'

components:
  schemas:
    StationExternal:
      type: object
      required:
        - externalStationId
        - name
        - address
        - latitude
        - longitude
        - status
      properties:
        externalStationId:
          type: string
          description: "Внешний идентификатор АЗС"
          example: "station-moscow-001"
        name:
          type: string
          description: "Название АЗС"
          example: "АЗС Горючка №1"
        address:
          type: string
          description: "Полный адрес"
          example: "г. Москва, ул. Топливная, д. 1"
        latitude:
          type: number
          format: float
          description: "Широта"
          example: 55.7558
        longitude:
          type: number
          format: float
          description: "Долгота"
          example: 37.6173
        status:
          type: string
          enum: [ACTIVE, INACTIVE, MAINTENANCE]
          description: "Статус АЗС"
          example: ACTIVE
        isAI76_80:
          type: boolean
          description: "Наличие бензина АИ-76/80"
          example: false
        isAI92:
          type: boolean
          description: "Наличие бензина АИ-92"
          example: true
        isAI95:
          type: boolean
          description: "Наличие бензина АИ-95"
          example: true
        isAI98:
          type: boolean
          description: "Наличие бензина АИ-98"
          example: true
        isDT:
          type: boolean
          description: "Наличие дизельного топлива"
          example: true
        isGas:
          type: boolean
          description: "Наличие газа"
          example: false
        isAutoWWashing:
          type: boolean
          description: "Наличие автоматической мойки"
          example: true
        isCafe:
          type: boolean
          description: "Наличие кафе"
          example: true
        isHandWWashing:
          type: boolean
          description: "Наличие ручной мойки"
          example: false
        isRentTrailer:
          type: boolean
          description: "Аренда прицепов"
          example: false
        isTireInflation:
          type: boolean
          description: "Наличие подкачки шин"
          example: true
        isVacuumCleaner:
          type: boolean
          description: "Наличие пылесоса"
          example: true
        isAdBlue:
          type: boolean
          description: "Наличие AdBlue"
          example: true

    ErrorResponse:
      type: object
      properties:
        code:
          type: string
          description: "Код ошибки"
          example: "INTERNAL_ERROR"
        message:
          type: string
          description: "Сообщение об ошибке"
          example: "Внутренняя ошибка сервера"
        details:
          type: string
          description: "Детали ошибки"
          example: "Произошла непредвиденная ошибка при обработке запроса"
        timestamp:
          type: string
          format: date-time
          description: "Время возникновения ошибки"
          example: "2024-12-03T12:00:00Z"
      required:
        - code
        - message

  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: "API ключ для доступа к системе управления АЗС"

security:
  - ApiKeyAuth: []