openapi: 3.0.3

info:
  version: v1
  title: API de Autenticação DeliveryVip
  description: >-
    Emissão e gestão dos access tokens OAuth 2.0 usados nas demais APIs da DeliveryVip.
    Os tokens são opacos (não são JWT) e devem ser enviados no header
    `Authorization: Bearer <token>`. Todas as requisições ao endpoint de token devem usar
    `Content-Type: application/x-www-form-urlencoded`.

servers:
  - url: https://api.deliveryvip.com.br
    description: Produção

tags:
  - name: OAuth
    description: Emissão, renovação, revogação e inspeção de tokens OAuth 2.0.

paths:
  /authentication/v1/oauth/token:
    post:
      summary: Obter access token
      description: >-
        Emite um novo access token. Fluxos suportados:


        - `client_credentials`: autenticação servidor a servidor com `client_id` e `client_secret`.
        Não retorna `refresh_token`; quando o token expirar, solicite um novo com as mesmas credenciais.

        - `authorization_code`: troca o código obtido na tela de autorização do painel por um token.
        Retorna `refresh_token`.

        - `refresh_token`: renova um token emitido pelo fluxo `authorization_code`.


        As credenciais do cliente podem ser enviadas no corpo (`client_id`/`client_secret`) ou via
        HTTP Basic. Tokens expiram em 24 horas. Enquanto não tiver decorrido 80% da validade de um
        token ativo do mesmo cliente e escopo, esse mesmo token é devolvido em vez de um novo. Mantenha o `client_secret` em segurança.
      operationId: createToken
      security:
        - basicAuth: []
        - {}
      tags:
        - OAuth
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
                - grant_type
              properties:
                grant_type:
                  description: Tipo de concessão OAuth.
                  type: string
                  enum:
                    - client_credentials
                    - authorization_code
                    - refresh_token
                  example: client_credentials
                client_id:
                  description: Identificador do cliente (aplicativo).
                  type: string
                  example: seu-client-id
                client_secret:
                  description: Segredo do cliente.
                  type: string
                  example: seu-client-secret
                scope:
                  description: >-
                    Escopos solicitados, separados por espaço. Escopos disponíveis: `od.all` (padrão),
                    `dv.all`, `dv.partner`, `dv.marketplace` e `dv.loyalty`. Só é possível solicitar
                    escopos habilitados para o aplicativo. Quando omitido, é usado `od.all`.
                  type: string
                  example: od.all
                code:
                  description: Código de autorização. Obrigatório quando `grant_type` é `authorization_code`.
                  type: string
                  example: 4a1b2c3d4e5f
                redirect_uri:
                  description: >-
                    URI de redirecionamento usada na autorização. Obrigatória quando `grant_type` é
                    `authorization_code`.
                  type: string
                  example: https://exemplo.com.br/oauth/callback
                refresh_token:
                  description: Refresh token recebido anteriormente. Obrigatório quando `grant_type` é `refresh_token`.
                  type: string
                  example: 8f3c2b1a9d7e6f5a4b3c2d1e0f9a8b7c
      responses:
        "200":
          description: Token emitido.
          content:
            application/json:
              schema:
                type: object
                properties:
                  access_token:
                    description: Access token opaco.
                    type: string
                    example: 2YotnFZFEjr1zCsicMWpAA
                  token_type:
                    description: Tipo do token, sempre `Bearer`.
                    type: string
                    example: Bearer
                  expires_in:
                    description: Tempo restante de validade do token, em segundos.
                    type: integer
                    example: 86400
                  refresh_token:
                    description: >-
                      Token para renovar o access token sem nova autorização. Presente apenas
                      nos fluxos `authorization_code` e `refresh_token`.
                    type: string
                    example: 8f3c2b1a9d7e6f5a4b3c2d1e0f9a8b7c
                  scope:
                    description: Escopos concedidos, separados por espaço.
                    type: string
                    example: od.all
                  created_at:
                    description: Momento de emissão do token (Unix timestamp, em segundos).
                    type: integer
                    example: 1639571898
        "400":
          description: >-
            Requisição inválida: parâmetro ausente, `grant_type` não suportado, código ou refresh
            token inválido, ou escopo não permitido.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/oauthError"
        "401":
          description: Credenciais do cliente inválidas (`invalid_client`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/oauthError"

  /authentication/v1/oauth/revoke:
    post:
      tags:
        - OAuth
      summary: Revogar token
      description: >-
        Revoga um access token ou refresh token antes da expiração (RFC 7009). O token precisa
        pertencer ao cliente autenticado. Responde 200 também quando o token é desconhecido ou já
        estava inválido.
      operationId: revokeToken
      security:
        - basicAuth: []
        - {}
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
                - token
              properties:
                token:
                  description: Access token ou refresh token a revogar.
                  type: string
                  example: 2YotnFZFEjr1zCsicMWpAA
                client_id:
                  description: Identificador do cliente. Pode ser enviado via HTTP Basic.
                  type: string
                  example: seu-client-id
                client_secret:
                  description: Segredo do cliente. Pode ser enviado via HTTP Basic.
                  type: string
                  example: seu-client-secret
      responses:
        "200":
          description: Token revogado (ou já inválido). Corpo vazio (`{}`).
          content:
            application/json:
              schema:
                type: object
        "403":
          description: >-
            Cliente não autenticado ou sem permissão para revogar o token informado
            (`unauthorized_client`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/oauthError"

  /authentication/v1/oauth/introspect:
    post:
      tags:
        - OAuth
      summary: Inspecionar token
      description: >-
        Retorna os metadados de um token, incluindo se ele está ativo (RFC 7662). A requisição deve
        ser autenticada com as credenciais do cliente (HTTP Basic ou `client_id`/`client_secret` no
        corpo) ou com um access token válido no header `Authorization: Bearer`. Para tokens
        inativos, a resposta é apenas `{"active": false}`.
      operationId: introspectToken
      security:
        - basicAuth: []
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
                - token
              properties:
                token:
                  description: Token a inspecionar.
                  type: string
                  example: 2YotnFZFEjr1zCsicMWpAA
                client_id:
                  description: Identificador do cliente, quando não for usado HTTP Basic nem Bearer.
                  type: string
                  example: seu-client-id
                client_secret:
                  description: Segredo do cliente, quando não for usado HTTP Basic nem Bearer.
                  type: string
                  example: seu-client-secret
      responses:
        "200":
          description: Resultado da inspeção.
          content:
            application/json:
              schema:
                type: object
                required:
                  - active
                properties:
                  active:
                    type: boolean
                    description: Indica se o token está ativo.
                    example: true
                  scope:
                    type: string
                    description: Escopos do token, separados por espaço.
                    example: od.all
                  client_id:
                    type: string
                    description: Identificador do aplicativo dono do token.
                    example: RlvxmDiOqtML0MTq9Nvupuf5f0wprMa7pvNriMQyZ4A
                  token_type:
                    type: string
                    description: Tipo do token, sempre `Bearer`.
                    example: Bearer
                  exp:
                    type: integer
                    description: Momento de expiração (Unix timestamp, em segundos).
                    example: 1639658298
                  iat:
                    type: integer
                    description: Momento de emissão (Unix timestamp, em segundos).
                    example: 1639571898
        "400":
          description: Requisição sem credenciais do cliente nem access token (`invalid_request`).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/oauthError"
        "401":
          description: Credenciais do cliente ou access token inválidos.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/oauthError"

  /authentication/v1/oauth/token/info:
    get:
      tags:
        - OAuth
      summary: Consultar token atual
      description: >-
        Retorna informações sobre o access token enviado no header `Authorization`, como validade
        restante, escopos e o aplicativo ao qual pertence.
      operationId: getTokenInfo
      security:
        - bearerAuth: []
      responses:
        "200":
          description: Informações do access token.
          content:
            application/json:
              schema:
                type: object
                properties:
                  resource_owner_id:
                    type: string
                    nullable: true
                    description: >-
                      Identificador do dono do recurso. Nulo em tokens `client_credentials`
                      emitidos sem dono.
                    example: null
                  resource_owner_type:
                    type: string
                    nullable: true
                    description: Tipo do dono do recurso. Nulo quando não há dono.
                    example: null
                  scope:
                    type: array
                    description: Escopos do token.
                    items:
                      type: string
                    example:
                      - od.all
                  expires_in:
                    type: integer
                    description: Tempo restante de validade, em segundos.
                    example: 86400
                  application:
                    type: object
                    properties:
                      uid:
                        type: string
                        description: Identificador (`client_id`) do aplicativo dono do token.
                        example: RlvxmDiOqtML0MTq9Nvupuf5f0wprMa7pvNriMQyZ4A
                  created_at:
                    type: integer
                    description: Momento de emissão (Unix timestamp, em segundos).
                    example: 1639571898
        "401":
          description: Access token ausente, inválido ou expirado.

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Access token opaco obtido em `/authentication/v1/oauth/token`.
    basicAuth:
      type: http
      scheme: basic
      description: "`client_id` como usuário e `client_secret` como senha."
  schemas:
    oauthError:
      type: object
      description: Erro no formato OAuth 2.0 (RFC 6749, seção 5.2).
      properties:
        error:
          type: string
          description: Código do erro.
          example: invalid_client
        error_description:
          type: string
          description: Descrição legível do erro.
          example: A autenticação do cliente falhou.
