openapi: 3.1.0
info:
  title: Az.pague API
  version: 1.0.0
  description: API REST da Az.pague para criação de vendas, cobranças, consulta de transações e gerenciamento de assinaturas.

servers:
  - url: https://azpague.com.br
    description: Produção
  - url: https://sandbox.azpag.dev
    description: Sandbox

tags:
  - name: Vendas
    description: Criação e consulta de vendas (pedidos)
  - name: Assinaturas
    description: Consulta e gerenciamento de assinaturas (vendas recorrentes)
  - name: Cobranças
    description: Criação e gerenciamento de cobranças (links de pagamento) avulsas e em lote

security:
  - BearerAuth: []

paths:
  # ── Vendas ──────────────────────────────────────────────
  /api/v1/order:
    get:
      summary: Listar vendas
      operationId: listOrders
      tags: [Vendas]
      parameters:
        - name: page
          in: query
          schema:
            type: integer
        - name: from
          in: query
          description: Data de início do filtro de pedidos.
          schema:
            type: string
            format: date
        - name: to
          in: query
          description: Data de fim do filtro de pedidos.
          schema:
            type: string
            format: date
        - name: status
          in: query
          description: |
            Status para filtro dos pedidos. Aceita múltiplos valores separados por vírgula
            (ex: `paid,unpaid`).
          schema:
            type: string
            enum: [created, paid, unpaid, waiting_payment, chargeback, refund, canceled, complete, pending, risk_analysis, dispute]
        - name: src
          in: query
          description: Parâmetro utilizado no momento do pedido para identificar a transação.
          schema:
            type: string
        - name: ref
          in: query
          description: Parâmetro utilizado no momento do pedido para identificar a transação.
          schema:
            type: string
        - name: product_id
          in: query
          description: ID do produto para filtrar pedidos.
          schema:
            type: integer
        - name: taxvat
          in: query
          description: CPF ou CNPJ do comprador para filtrar pedidos.
          schema:
            type: string
      responses:
        '200':
          description: Lista de vendas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Order'
                  links:
                    $ref: '#/components/schemas/PaginationLinks'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

    post:
      summary: Criar venda
      operationId: createOrder
      tags: [Vendas]
      description: |
        Crie uma venda através do checkout transparente. Para esse endpoint, é necessário
        ter criado o produto e os checkouts no painel administrativo.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderInput'
      responses:
        '200':
          description: Venda criada
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateOrderResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  /api/v1/order/single:
    post:
      summary: Criar venda avulsa
      operationId: createSingleOrder
      tags: [Vendas]
      description: |
        Cria um pedido e processa o pagamento no mesmo request (pagamento direto /
        checkout transparente síncrono). Os itens são avulsos (`sku`, `title`, `unit_price`,
        `quantity`) e não exigem cadastro prévio de produtos no painel.

        O resultado do pagamento é indicado pelos campos `success`/`hasError` no corpo.
        Requisições originadas de IPs da AWS (`amazonaws`) são rejeitadas.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SingleOrderInput'
      responses:
        '200':
          description: |
            Pedido criado. O pagamento pode ter sido aprovado (`success: true`) ou recusado
            (`hasError: true`, `status: unpaid`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateSingleOrderResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: Empresa em moderação.
          content:
            application/json:
              schema:
                type: object
                properties:
                  hasError:
                    type: boolean
                    example: true
                  response:
                    type: string
                    example: "No momento não foi possível processar sua solicitação..."
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  /api/v1/order/{order_number}:
    get:
      summary: Consultar venda
      operationId: getOrder
      tags: [Vendas]
      parameters:
        - name: order_number
          in: path
          required: true
          description: Código da transação.
          schema:
            type: string
      responses:
        '200':
          description: Dados da venda
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: '#/components/schemas/Order'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  /api/v1/order/status:
    get:
      summary: Listar status disponíveis
      operationId: listOrderStatuses
      tags: [Vendas]
      description: Retorna todos os status de pedido disponíveis no sistema com seus títulos de exibição.
      responses:
        '200':
          description: Lista de status
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        status:
                          type: string
                        title:
                          type: string
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  # ── Assinaturas ─────────────────────────────────────────
  /api/v1/subscriber:
    get:
      summary: Listar assinaturas
      operationId: listSubscribers
      tags: [Assinaturas]
      parameters:
        - name: page
          in: query
          description: Informa número da página em caso de paginação disponível.
          schema:
            type: integer
        - name: next_charge
          in: query
          description: Filtro pela data de próxima cobrança.
          schema:
            type: string
            format: date
        - name: status
          in: query
          description: Status disponíveis para filtro das assinaturas.
          schema:
            type: string
            enum: [subscriber_canceled, subscriber_overdue, subscriber_active]
        - name: checkout_id
          in: query
          description: Slug do checkout para pesquisar assinaturas realizadas deste plano.
          schema:
            type: string
        - name: token
          in: query
          description: Informe o token da assinatura para pesquisar.
          schema:
            type: string
        - name: email
          in: query
          description: Informe o e-mail do assinante para pesquisar.
          schema:
            type: string
      responses:
        '200':
          description: Lista de assinaturas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Subscriber'
                  links:
                    $ref: '#/components/schemas/PaginationLinks'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  /api/v1/subscriber/{token}:
    get:
      summary: Consultar assinatura
      operationId: getSubscriber
      tags: [Assinaturas]
      parameters:
        - name: token
          in: path
          required: true
          description: Token único de identificação da assinatura.
          schema:
            type: string
      responses:
        '200':
          description: Dados da assinatura
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    $ref: '#/components/schemas/Subscriber'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  /api/v1/subscriber/{token}/cancel:
    delete:
      summary: Cancelar assinatura
      operationId: cancelSubscriber
      tags: [Assinaturas]
      parameters:
        - name: token
          in: path
          required: true
          description: Token único de identificação da assinatura.
          schema:
            type: string
      responses:
        '200':
          description: Assinatura cancelada
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                hasError: false
                response: "Subscription successfully canceled."
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  # ── Cobranças (Links de Pagamento) ─────────────────────
  /api/v1/payment-link:
    post:
      summary: Criar cobrança
      operationId: createPaymentLink
      tags: [Cobranças]
      description: Cria uma cobrança (link de pagamento) avulsa para envio ao cliente.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaymentLinkInput'
      responses:
        '201':
          description: Cobrança criada
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/PaymentLink'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

    get:
      summary: Listar cobranças
      operationId: listPaymentLinks
      tags: [Cobranças]
      description: Lista as cobranças (links de pagamento) cadastradas.
      parameters:
        - name: page
          in: query
          schema:
            type: integer
      responses:
        '200':
          description: Lista de cobranças
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/PaymentLink'
                  links:
                    $ref: '#/components/schemas/PaginationLinks'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  /api/v1/payment-link/{slug}:
    get:
      summary: Consultar cobrança
      operationId: getPaymentLink
      tags: [Cobranças]
      parameters:
        - name: slug
          in: path
          required: true
          description: Identificador único da cobrança.
          schema:
            type: string
      responses:
        '200':
          description: Dados da cobrança
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/PaymentLink'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

    put:
      summary: Atualizar cobrança
      operationId: updatePaymentLink
      tags: [Cobranças]
      parameters:
        - name: slug
          in: path
          required: true
          description: Identificador único da cobrança.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaymentLinkInput'
      responses:
        '200':
          description: Cobrança atualizada
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/PaymentLink'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

    delete:
      summary: Remover cobrança
      operationId: deletePaymentLink
      tags: [Cobranças]
      description: Remove uma cobrança que ainda não foi paga.
      parameters:
        - name: slug
          in: path
          required: true
          description: Identificador único da cobrança.
          schema:
            type: string
      responses:
        '200':
          description: Cobrança removida
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                hasError: false
                response: "Payment link successfully deleted."
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  # ── Cobranças em Lote ───────────────────────────────────
  /api/v1/payment-link-bulk:
    post:
      summary: Criar cobranças em lote
      operationId: createPaymentLinkBulk
      tags: [Cobranças]
      description: |
        Gera múltiplas cobranças em uma única requisição, com processamento assíncrono.
        Máximo de 50 clientes por requisição.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaymentLinkBulkInput'
      responses:
        '202':
          description: Lote aceito para processamento
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/PaymentLinkBulk'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

    get:
      summary: Listar lotes
      operationId: listPaymentLinkBulks
      tags: [Cobranças]
      description: Lista os lotes de cobranças cadastrados.
      parameters:
        - name: page
          in: query
          schema:
            type: integer
      responses:
        '200':
          description: Lista de lotes
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/PaymentLinkBulk'
                  links:
                    $ref: '#/components/schemas/PaginationLinks'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  /api/v1/payment-link-bulk/{token}:
    get:
      summary: Consultar lote
      operationId: getPaymentLinkBulk
      tags: [Cobranças]
      description: Consulta um lote específico e as cobranças geradas.
      parameters:
        - name: token
          in: path
          required: true
          description: Token do lote.
          schema:
            type: string
      responses:
        '200':
          description: Dados do lote com cobranças geradas
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    allOf:
                      - $ref: '#/components/schemas/PaymentLinkBulk'
                      - type: object
                        properties:
                          payment_links:
                            type: array
                            items:
                              $ref: '#/components/schemas/PaymentLink'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  /api/v1/payment-link-bulk/{token}/status:
    get:
      summary: Status do lote
      operationId: getPaymentLinkBulkStatus
      tags: [Cobranças]
      description: Consulta o progresso de processamento de um lote.
      parameters:
        - name: token
          in: path
          required: true
          description: Token do lote.
          schema:
            type: string
      responses:
        '200':
          description: Status do processamento
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      token:
                        type: string
                      status:
                        type: string
                        enum: [pending, processing, completed, partial_failure, canceled]
                      total:
                        type: integer
                      processed:
                        type: integer
                      percent:
                        type: number
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  /api/v1/payment-link-bulk/{token}/customers:
    post:
      summary: Adicionar clientes ao lote
      operationId: addCustomersToPaymentLinkBulk
      tags: [Cobranças]
      description: Adiciona novos clientes a um lote existente. Máximo de 50 clientes por requisição.
      parameters:
        - name: token
          in: path
          required: true
          description: Token do lote.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [customers]
              properties:
                customers:
                  type: array
                  minItems: 1
                  maxItems: 50
                  items:
                    $ref: '#/components/schemas/PaymentLinkBulkCustomer'
      responses:
        '202':
          description: Clientes adicionados ao lote
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/PaymentLinkBulk'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

  /api/v1/payment-link-bulk/{token}/cancel:
    post:
      summary: Cancelar lote
      operationId: cancelPaymentLinkBulk
      tags: [Cobranças]
      description: Cancela um lote em processamento. Cobranças ainda não geradas deixam de ser processadas.
      parameters:
        - name: token
          in: path
          required: true
          description: Token do lote.
          schema:
            type: string
      responses:
        '200':
          description: Lote cancelado
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiResponse'
              example:
                hasError: false
                response: "Bulk successfully canceled."
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: Token de API criado no painel administrativo em Plugins > API.

  schemas:
    # ── Vendas ──────────────────────────────────────────
    Order:
      type: object
      properties:
        token:
          type: string
          format: uuid
          example: "3e1d9542-09fe-4b8b-9800-38f99f5b2147"
        order_number:
          type: string
          example: "1654112455"
        public_key:
          type: string
          example: "t9rb"
        status:
          type: string
          enum: [created, paid, unpaid, refund, waiting_payment, chargeback, canceled, complete, pending, risk_analysis, dispute]
          example: paid
        origin:
          type: string
          example: checkout
        src:
          type: string
          nullable: true
        ref:
          type: string
          nullable: true
        created_at:
          type: string
          example: "2021-08-01 16:40:55"
        updated_at:
          type: string
          example: "2022-06-01 16:40:55"
        checkout:
          type: object
          nullable: true
          properties:
            name:
              type: string
              description: Título do checkout.
            key:
              type: string
              description: Slug do checkout.
            product:
              type: object
              nullable: true
              properties:
                title:
                  type: string
                sku:
                  type: string
        customer:
          type: object
          properties:
            email:
              type: string
            fullname:
              type: string
            taxvat:
              type: string
            telephone:
              type: string
        address:
          $ref: '#/components/schemas/Address'
        payment:
          type: object
          properties:
            name:
              type: string
              example: "Cartão de Crédito"
            method:
              type: string
              enum: [credit, bank_slip, pix]
            link_to_pay:
              type: string
            digitable:
              type: string
              nullable: true
            due_date:
              type: string
              nullable: true
            card:
              type: object
              nullable: true
              properties:
                token:
                  type: string
                brand:
                  type: string
                last_digits:
                  type: string
        totals:
          type: object
          properties:
            subtotal:
              type: number
              nullable: true
            fee:
              type: number
              nullable: true
            total:
              type: number
              nullable: true
            net:
              type: number
              nullable: true
        items:
          type: array
          items:
            $ref: '#/components/schemas/OrderItem'

    OrderInput:
      type: object
      required: [checkout_id, customer, address, payment]
      properties:
        checkout_id:
          type: string
          description: Slug do checkout que será realizado a transação.
        src:
          type: string
          description: Referência externa para identificar o pedido.
        ref:
          type: string
          description: Referência externa para identificar o pedido.
        coupon_code:
          type: string
          description: Código do cupom de desconto a aplicar.
          maxLength: 64
        customer:
          type: object
          required: [fullname, taxvat, email, telephone]
          properties:
            fullname:
              type: string
              description: Nome do comprador. Em caso de empresas, informar a Razão Social.
            taxvat:
              type: string
              description: Documento do comprador (CPF ou CNPJ, apenas números).
            email:
              type: string
            telephone:
              type: string
              description: Telefone do comprador (apenas números).
        address:
          type: object
          required: [postcode, street, number, district, city, region]
          properties:
            postcode:
              type: string
              description: "CEP no formato 00000-000."
              example: "01001-000"
            street:
              type: string
            number:
              type: string
            complement:
              type: string
            district:
              type: string
            city:
              type: string
            region:
              type: string
              description: UF do endereço do comprador.
        items:
          type: array
          description: Lista de produtos adicionais ao checkout.
          items:
            $ref: '#/components/schemas/OrderItemInput'
        payment:
          type: object
          required: [method]
          properties:
            method:
              type: string
              enum: [credit, bank_slip, pix]
            expiration:
              type: integer
              description: Tempo limite em minutos para atualização do status. Padrão de 10 minutos. Disponível para cartão de crédito ou Pix.
            installments:
              type: integer
              description: Número de parcelas (1–12). Obrigatório para cartão de crédito.
              minimum: 1
              maximum: 12
            apply_interest:
              type: boolean
              description: Aplicar juros ao valor total informado.
            custom_total:
              type: number
              description: Valor customizado para o total da transação.
            custom_quantity:
              type: integer
              description: Quantidade de itens que representam essa transação.
            card:
              type: object
              description: Obrigatório se o method for credit. Envie os dados do cartão OU um token de cartão salvo.
              properties:
                holder:
                  type: string
                  description: Nome impresso no cartão (apenas letras e espaços, máx. 25 caracteres).
                  maxLength: 25
                number:
                  type: string
                expiration:
                  type: string
                  description: "Data de expiração no formato MM/YYYY."
                  example: "12/2025"
                security:
                  type: string
                  description: Código de segurança (CVV), 3 ou 4 dígitos.
                token:
                  type: string
                  description: Token de cartão salvo (alternativa a enviar os dados completos do cartão).
        shipping:
          type: object
          description: Dados de frete (quando aplicável).
          properties:
            method:
              type: string
            name:
              type: string
            total:
              type: number

    OrderItemInput:
      type: object
      properties:
        product_id:
          type: integer
        sku:
          type: string
        title:
          type: string
        unit_price:
          type: number
        quantity:
          type: integer

    OrderItem:
      type: object
      properties:
        id:
          type: integer
        order_id:
          type: integer
        product_id:
          type: integer
          nullable: true
        sku:
          type: string
        title:
          type: string
        unit_price:
          type: number
        price_cost:
          type: number
          nullable: true
        quantity:
          type: integer
        created_at:
          type: string
        updated_at:
          type: string

    CreateOrderResponse:
      type: object
      properties:
        responseCode:
          type: integer
          example: 200
        responseData:
          type: string
          example: "Pedido criado com sucesso"
        success:
          type: boolean
        redirectAfterSuccess:
          type: string
          nullable: true
        data:
          type: object
          properties:
            order_number:
              type: string
            public_key:
              type: string
            uptoken:
              type: string
              format: uuid
        payment:
          type: object
          properties:
            link_to_pay:
              type: string
              nullable: true
            digitable_number:
              type: string
              nullable: true
            due_date:
              type: string
              nullable: true
            card:
              type: object
              nullable: true
              properties:
                token:
                  type: string
                brand:
                  type: string
                last_digits:
                  type: string

    SingleOrderInput:
      type: object
      required: [customer, address, items, payment]
      properties:
        customer:
          type: object
          required: [email, fullname, taxvat, telephone]
          properties:
            id:
              type: integer
              nullable: true
              description: ID de um cliente já existente (opcional).
            email:
              type: string
            fullname:
              type: string
              description: Nome do comprador. Em caso de empresas, informar a Razão Social.
            taxvat:
              type: string
              description: Documento do comprador (CPF ou CNPJ, apenas números).
            telephone:
              type: string
              description: Telefone do comprador.
        address:
          type: object
          required: [postcode, street, number, district, city, region]
          properties:
            postcode:
              type: string
              description: "CEP no formato 00000-000 (com hífen)."
              example: "01310-100"
            street:
              type: string
            number:
              type: integer
            complement:
              type: string
            district:
              type: string
              description: Bairro do endereço do comprador.
            city:
              type: string
            region:
              type: string
              description: UF do endereço do comprador.
        items:
          type: array
          description: Lista de itens avulsos do pedido (sem cadastro prévio de produtos).
          items:
            type: object
            required: [sku, title, unit_price, quantity]
            properties:
              sku:
                type: string
              title:
                type: string
              unit_price:
                type: number
              quantity:
                type: integer
        discount:
          type: object
          description: Desconto aplicado ao total do pedido.
          properties:
            total:
              type: number
        payment:
          type: object
          required: [method]
          properties:
            method:
              type: string
              enum: [credit, pix, bank_slip]
            installments:
              type: integer
              description: Número de parcelas (1–12). Obrigatório quando method for credit.
              minimum: 1
              maximum: 12
            expiration:
              type: integer
              nullable: true
              description: Validade do Pix/boleto.
            card:
              type: object
              description: Obrigatório quando method for credit. Envie os dados do cartão OU um token de cartão salvo.
              properties:
                holder:
                  type: string
                  description: Nome impresso no cartão (máx. 25 caracteres).
                  maxLength: 25
                number:
                  type: string
                expiration:
                  type: string
                  description: "Data de expiração no formato MM/YYYY, não vencida."
                  example: "12/2027"
                security:
                  type: string
                  description: Código de segurança do cartão (CVV).
                token:
                  type: string
                  description: Token de cartão salvo (alternativa a enviar os dados completos do cartão).

    CreateSingleOrderResponse:
      type: object
      properties:
        success:
          type: boolean
          description: "`true` quando o pagamento foi aprovado."
        hasError:
          type: boolean
          description: "`true` quando o pagamento foi recusado (pedido criado com status unpaid)."
        response:
          type: string
          example: "Pedido criado com sucesso"
        data:
          type: object
          properties:
            order_number:
              type: string
            public_key:
              type: string
            status:
              type: string
              enum: [paid, unpaid, waiting_payment]
        payment:
          type: object
          properties:
            tid:
              type: string
              nullable: true
            nsu:
              type: string
              nullable: true
            link_to_pay:
              type: string
              nullable: true
              description: "Rota de pagamento (ex.: Pix/boleto)."
            digitable_number:
              type: string
              nullable: true
              description: Linha digitável / copia-e-cola.
            due_date:
              type: string
              nullable: true
            card:
              type: object
              nullable: true
              description: Retornado apenas quando há pagamento com cartão.
              properties:
                token:
                  type: string
                brand:
                  type: string
                last_digits:
                  type: string

    # ── Cobranças ───────────────────────────────────────
    PaymentLinkInput:
      type: object
      required: [title, amount]
      properties:
        title:
          type: string
          description: Título exibido na página de cobrança. Limite de 150 caracteres.
          maxLength: 150
        description:
          type: string
          description: Texto auxiliar exibido para o cliente. Limite de 1000 caracteres.
          maxLength: 1000
        amount:
          type: number
          description: "Valor da cobrança. Ex: 99.90"
        additional_amount:
          type: number
          description: Valor adicional opcional, somado ao amount.
        bg_color:
          type: string
          description: "Cor de fundo da página em formato hexadecimal. Ex: #0d6efd"
        show_company_logo:
          type: boolean
          description: Exibe o logo da empresa na página de cobrança.
        expired_at:
          type: string
          format: date
          description: Data de expiração da cobrança no formato YYYY-MM-DD.
        expire_after_payment:
          type: boolean
          description: Invalida a cobrança após o primeiro pagamento confirmado.
        reference:
          type: string
          description: Referência externa para identificar a cobrança na sua aplicação. Limite de 100 caracteres.
          maxLength: 100
        enable_pix:
          type: boolean
          description: Habilita o pagamento via Pix.
        enable_credit:
          type: boolean
          description: Habilita o pagamento via cartão de crédito.
        enable_bank_slip:
          type: boolean
          description: Habilita o pagamento via boleto bancário.
        installments:
          type: integer
          description: Número máximo de parcelas permitidas no cartão (1 a 12).
          minimum: 1
          maximum: 12
        fee_mode:
          type: string
          description: "Modo de juros: none, interest ou customer_pay_fee."
          enum: [none, interest, customer_pay_fee]
        hide_customer_fields:
          type: boolean
          description: Oculta os campos de dados do cliente na página de cobrança.
        customer_name:
          type: string
        customer_email:
          type: string
        customer_phone:
          type: string
        customer_document:
          type: string
          description: CPF ou CNPJ do cliente, sem formatação.
        customer_cep:
          type: string
          description: CEP do cliente. O sistema carrega o endereço automaticamente via Correios.
        customer_number:
          type: string
          description: Número do endereço do cliente.
        payment_link_rule_token:
          type: string
          description: Token da régua de cobrança configurada no painel.

    PaymentLink:
      type: object
      properties:
        slug:
          type: string
          example: "pl_3kd0192"
        url:
          type: string
          example: "https://sandbox.azpag.dev/link/pl_3kd0192"
        title:
          type: string
        description:
          type: string
        amount:
          type: number
        additional_amount:
          type: number
        expired_at:
          type: string
          format: date
          nullable: true
        expire_after_payment:
          type: boolean
        reference:
          type: string
          nullable: true
        enable_pix:
          type: boolean
        enable_credit:
          type: boolean
        enable_bank_slip:
          type: boolean
        fee_mode:
          type: string
          enum: [none, interest, customer_pay_fee]
        installments:
          type: integer
        customer_name:
          type: string
          nullable: true
        customer_email:
          type: string
          nullable: true
        customer_phone:
          type: string
          nullable: true
        customer_document:
          type: string
          nullable: true
        hide_customer_fields:
          type: boolean
        paid_at:
          type: string
          nullable: true
        created_at:
          type: string

    PaymentLinkBulkInput:
      type: object
      required: [customers]
      properties:
        name:
          type: string
          description: Nome interno do lote para identificação no painel. Limite de 150 caracteres.
          maxLength: 150
        title:
          type: string
          description: Título padrão exibido na página de cobrança.
        description:
          type: string
          description: Texto auxiliar padrão das cobranças. Limite de 1000 caracteres.
          maxLength: 1000
        amount:
          type: number
          description: Valor padrão da cobrança. Caso omitido, é obrigatório informar o valor em cada cliente.
        additional_amount:
          type: number
        bg_color:
          type: string
        show_company_logo:
          type: boolean
        expired_at:
          type: string
          format: date
        expire_after_payment:
          type: boolean
        enable_pix:
          type: boolean
        enable_credit:
          type: boolean
        enable_bank_slip:
          type: boolean
        installments:
          type: integer
          minimum: 1
          maximum: 12
        fee_mode:
          type: string
          enum: [none, interest, customer_pay_fee]
        hide_customer_fields:
          type: boolean
        payment_link_rule_token:
          type: string
        customers:
          type: array
          minItems: 1
          maxItems: 50
          items:
            $ref: '#/components/schemas/PaymentLinkBulkCustomer'

    PaymentLinkBulkCustomer:
      type: object
      required: [amount]
      properties:
        amount:
          type: number
          description: "Valor cobrado desse cliente. Ex: 99.90"
        title:
          type: string
          description: Sobrescreve o título do lote para esse cliente.
        description:
          type: string
          description: Sobrescreve a descrição do lote.
        name:
          type: string
        email:
          type: string
        phone:
          type: string
          description: Telefone do cliente, com DDD.
        document:
          type: string
          description: CPF ou CNPJ do cliente, sem formatação.
        cep:
          type: string
          description: CEP do cliente. O sistema carrega o endereço automaticamente via Correios.
        number:
          type: string
          description: Número do endereço.
        reference:
          type: string
          description: Referência externa para identificar essa cobrança na sua aplicação.

    PaymentLinkBulk:
      type: object
      properties:
        token:
          type: string
          example: "bulk_3kd0192"
        name:
          type: string
        status:
          type: string
          enum: [pending, processing, completed, partial_failure, canceled]
        total:
          type: integer
        processed:
          type: integer
        percent:
          type: number
        created_at:
          type: string
        updated_at:
          type: string

    # ── Compartilhados ──────────────────────────────────
    Address:
      type: object
      properties:
        postcode:
          type: string
        street:
          type: string
        number:
          type: string
        complement:
          type: string
        city:
          type: string
        region:
          type: string
        district:
          type: string

    Subscriber:
      type: object
      properties:
        token:
          type: string
          format: uuid
          example: "8750f9c5-4e3a-4d59-be25-657cff0e9a34"
        status:
          type: string
          enum: [subscriber_active, subscriber_overdue, subscriber_canceled]
        link_to_pay:
          type: string
          nullable: true
          description: Presente apenas quando a assinatura está em atraso (overdue).
        customer:
          type: object
          properties:
            token:
              type: string
              description: Chave pública do cliente (key).
            email:
              type: string
            telephone:
              type: string
        subscription:
          type: object
          properties:
            from:
              type: string
              format: date
            to:
              type: string
              format: date
            next_charge:
              type: string
              format: date
              nullable: true
        checkout:
          type: object
          properties:
            slug:
              type: string
            title:
              type: string
            total:
              type: string
        payment:
          type: object
          properties:
            method:
              type: string
            card:
              type: object
              nullable: true
              description: Presente apenas quando o método de pagamento for cartão de crédito.
              properties:
                brand:
                  type: string
                last_digits:
                  type: string
                token:
                  type: string
        created_at:
          type: string

    PaginationLinks:
      type: object
      properties:
        first:
          type: string
        last:
          type: string
        prev:
          type: string
          nullable: true
        next:
          type: string
          nullable: true

    PaginationMeta:
      type: object
      properties:
        current_page:
          type: integer
        from:
          type: integer
        last_page:
          type: integer
        path:
          type: string
        per_page:
          type: integer
        to:
          type: integer
        total:
          type: integer

    ApiResponse:
      type: object
      properties:
        hasError:
          type: boolean
        response:
          description: Pode conter uma string com a descrição do erro ou um objeto.
          oneOf:
            - type: string
            - type: object
        data:
          type: object
          description: Caso seja criação de uma nova transação, irá retornar informações do pedido.

  responses:
    Unauthorized:
      description: Não houve permissão de acesso através da chave de API informada.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiResponse'
          example:
            hasError: true
            response: "Acesso não autorizado."
    NotFound:
      description: O recurso solicitado não existe.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiResponse'
          example:
            hasError: true
            response: "Not found"
    UnprocessableEntity:
      description: Parâmetros inválidos na validação das informações enviadas.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiResponse'
          example:
            hasError: true
            response:
              customer.email: ["O e-mail preenchido não é válido."]
    TooManyRequests:
      description: Quantidade de requisições maior que o permitido (90 por minuto).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiResponse'
          example:
            hasError: true
            response: "Too many requests."
    InternalError:
      description: Ocorreu um erro interno.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiResponse'
          example:
            hasError: true
            response: "Error on server, try again."
