openapi: 3.1.0
info:
  title: Master Wallet API
  version: 1.0.0
  description: >
    API REST da Master Wallet para criar e consultar cobranças Pix, consultar saldo
    e testar integrações. Valores monetários são enviados em centavos de BRL.
servers:
  - url: https://api.masterwallet.app/v1
    description: Produção
security:
  - bearerAuth: []
tags:
  - name: Geral
  - name: Cobranças
  - name: Carteira
  - name: Sandbox
paths:
  /:
    get:
      tags: [Geral]
      summary: Informações da API
      responses:
        "200":
          description: Versão e rotas disponíveis para a chave autenticada.
          content:
            application/json:
              schema:
                type: object
                properties:
                  name: { type: string, example: Master Wallet API }
                  version: { type: string, example: 1.0.0 }
                  documentation: { type: string, example: /docs/api }
                  openapi: { type: string, example: /docs/openapi.yaml }
                  endpoints:
                    type: array
                    items: { type: string }
  /charges:
    get:
      tags: [Cobranças]
      summary: Listar cobranças
      description: Retorna cobranças da conta e do ambiente vinculados à chave. O cursor before usa a data ISO retornada em next_before.
      parameters:
        - in: query
          name: limit
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
        - in: query
          name: before
          description: Data ISO para paginação, obtida do campo next_before.
          schema:
            type: string
            format: date-time
        - in: query
          name: before_id
          description: UUID obtido do campo next_before_id. Deve ser enviado junto com before.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Lista paginada.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: { $ref: "#/components/schemas/Charge" }
                  has_more: { type: boolean }
                  next_before: { type: [string, "null"], format: date-time }
                  next_before_id: { type: [string, "null"], format: uuid }
        "401": { $ref: "#/components/responses/Unauthorized" }
        "429": { $ref: "#/components/responses/RateLimited" }
    post:
      tags: [Cobranças]
      summary: Criar cobrança Pix
      description: >
        A chave test cria uma cobrança simulada, sem Pix real. A chave live cria
        uma cobrança Pix pela gateway ativa. Envie sempre uma Idempotency-Key única
        por intenção de cobrança. O valor deve ser informado em centavos.
      parameters:
        - in: header
          name: Idempotency-Key
          required: true
          description: Chave de idempotência de 8 a 128 caracteres.
          schema:
            type: string
            minLength: 8
            maxLength: 128
            pattern: "^[A-Za-z0-9._:-]{8,128}$"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [amount]
              properties:
                amount:
                  type: integer
                  minimum: 50
                  maximum: 100000000
                  description: Valor em centavos de BRL (R$ 0,50 a R$ 1.000.000,00).
                  example: 2590
                external_reference:
                  type: [string, "null"]
                  maxLength: 100
                  example: pedido-2026-000123
                description:
                  type: [string, "null"]
                  maxLength: 120
                  example: Pedido #123
      responses:
        "201":
          description: Cobrança criada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChargeResponse"
        "202":
          description: Solicitação em conciliação. Consulte a cobrança antes de tentar novamente.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChargeResponse"
        "400": { $ref: "#/components/responses/BadRequest" }
        "401": { $ref: "#/components/responses/Unauthorized" }
        "403": { $ref: "#/components/responses/Forbidden" }
        "409": { $ref: "#/components/responses/Conflict" }
        "429": { $ref: "#/components/responses/RateLimited" }
        "502": { $ref: "#/components/responses/ProviderError" }
        "503": { $ref: "#/components/responses/Unavailable" }
  /charges/{id}:
    get:
      tags: [Cobranças]
      summary: Consultar cobrança
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Cobrança encontrada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChargeResponse"
        "401": { $ref: "#/components/responses/Unauthorized" }
        "404":
          description: Cobrança não encontrada para a conta e ambiente da chave.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ErrorResponse" }
  /balance:
    get:
      tags: [Carteira]
      summary: Consultar saldo
      description: Disponível somente com chave live. Retorna valores em centavos.
      responses:
        "200":
          description: Saldo e pendências da carteira.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      currency: { type: string, enum: [BRL] }
                      balance_cents: { type: integer }
                      locked_balance_cents: { type: integer }
                      med_fee_debt_cents: { type: integer }
                      med_amount_debt_cents: { type: integer }
                      updated_at: { type: string, format: date-time }
        "401": { $ref: "#/components/responses/Unauthorized" }
        "403":
          description: Chave test não pode consultar saldo real.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ErrorResponse" }
        "404": { description: Carteira não encontrada. }
  /sandbox/charges/{id}/approve:
    post:
      tags: [Sandbox]
      summary: Simular aprovação de cobrança de teste
      description: >
        Somente chave mw_test_. Altera o estado da cobrança simulada e enfileira
        charge.paid se o webhook estiver configurado. Não cria Pix nem movimenta dinheiro real.
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Cobrança simulada aprovada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChargeResponse"
        "403": { $ref: "#/components/responses/Forbidden" }
        "404":
          description: Cobrança de teste não encontrada.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ErrorResponse" }
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: Master Wallet API Key
  schemas:
    Charge:
      type: object
      properties:
        id: { type: string, format: uuid }
        object: { type: string, enum: [charge] }
        amount:
          type: object
          properties:
            value: { type: integer, description: Valor em centavos. }
            currency: { type: string, enum: [BRL] }
        fee_cents: { type: integer }
        net_amount_cents: { type: integer }
        status:
          type: string
          enum: [creating, pending, unknown, paid, failed, review]
        external_reference: { type: [string, "null"] }
        description: { type: [string, "null"] }
        pix:
          oneOf:
            - type: "null"
            - type: object
              properties:
                copy_paste: { type: [string, "null"] }
                qr_code_base64: { type: [string, "null"] }
        created_at: { type: string, format: date-time }
        expires_at: { type: [string, "null"], format: date-time }
        paid_at: { type: [string, "null"], format: date-time }
        sandbox: { type: boolean }
    ChargeResponse:
      type: object
      properties:
        data: { $ref: "#/components/schemas/Charge" }
        warning:
          type: object
          properties:
            code: { type: string }
            message: { type: string }
        already_paid: { type: boolean }
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          properties:
            code: { type: string }
            message: { type: string }
    Error:
      $ref: "#/components/schemas/ErrorResponse"
  responses:
    BadRequest:
      description: Requisição inválida.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    Unauthorized:
      description: Chave inválida, ausente ou revogada.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    Forbidden:
      description: A chave não tem permissão para esta operação.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    Conflict:
      description: Conflito de idempotência ou solicitação em andamento.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    RateLimited:
      description: Limite de requisições excedido.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    ProviderError:
      description: Falha ao criar cobrança no provedor de pagamentos.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    Unavailable:
      description: Integração ou operação temporariamente indisponível.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
