openapi: 3.0.3
info:
  title: Eleva Payments API
  version: "1.0"
  description: |
    API REST para cobranças Pix e cartão, recebimento em USDT, split, consultas, saques via Pix e webhooks.

    Autenticação: envie `Authorization: Bearer SEU_TOKEN` e `X-Client-ID: SEU_CLIENT_ID` em todas as chamadas.
    Limite: 120 requisições por minuto por token (429 + Retry-After acima disso).

    Webhooks: POST JSON para a URL da credencial, assinado com HMAC-SHA256 usando o token.
    Header `X-Webhook-Signature-V2: t={timestamp},v1={hmac(timestamp + "." + corpo)}`.
    Documentação completa: https://elevapayments.squareweb.app/documentacao
servers:
  - url: https://elevapayments.squareweb.app/api/v1
security:
  - bearerAuth: []
    clientId: []
tags:
  - name: Pix
  - name: Cartão
  - name: Consultas
  - name: Saques
paths:
  /payments/pix:
    post:
      tags: [Pix]
      summary: Criar cobrança Pix
      operationId: createPix
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/PixRequest' }
            example:
              amount: 49.90
              payer_name: Maria Souza
              payer_email: maria@exemplo.com
              payer_cpf: "52998224725"
              description: "Pedido #1042"
      responses:
        "201":
          description: Cobrança criada (aguardando pagamento)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean, example: true }
                  data: { $ref: '#/components/schemas/PixCharge' }
        "400": { $ref: '#/components/responses/Error' }
        "401": { $ref: '#/components/responses/Error' }
        "403": { $ref: '#/components/responses/Error' }
        "422": { $ref: '#/components/responses/ValidationError' }
        "429": { $ref: '#/components/responses/Error' }
        "500": { $ref: '#/components/responses/Error' }
  /cashin/pix:
    post:
      tags: [Pix]
      summary: Depósito Pix na própria conta
      operationId: createCashin
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [amount]
              properties:
                amount: { type: number, format: float, minimum: 1, example: 100.00 }
                payer_name: { type: string }
      responses:
        "200":
          description: QR Code do depósito
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  transaction:
                    type: object
                    properties:
                      uuid: { type: string, format: uuid }
                      amount_gross: { type: number }
                      amount_net: { type: number }
                      fee: { type: number }
                      status: { type: string }
                      expires_at: { type: string, format: date-time }
                  qr_code: { type: string }
        "422": { $ref: '#/components/responses/ValidationError' }
  /payments/credit-card:
    post:
      tags: [Cartão]
      summary: Cobrar no cartão de crédito
      operationId: createCreditCard
      description: Os dados do cartão não são armazenados. Chame apenas do seu servidor.
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: '#/components/schemas/CardRequest' }
      responses:
        "201":
          description: Aprovada
          content:
            application/json:
              schema: { $ref: '#/components/schemas/CardResult' }
        "202":
          description: Requer autenticação 3DS (authentication_url) ou está em conferência (processing)
          content:
            application/json:
              schema: { $ref: '#/components/schemas/CardResult' }
        "402":
          description: Recusada pelo banco emissor
          content:
            application/json:
              schema: { $ref: '#/components/schemas/CardResult' }
        "403": { $ref: '#/components/responses/Error' }
        "422": { $ref: '#/components/responses/ValidationError' }
  /payments/{uuid}:
    get:
      tags: [Consultas]
      summary: Consultar cobrança
      description: Para cobranças pendentes, o status é conferido na adquirente no momento da consulta.
      operationId: getPayment
      parameters:
        - $ref: '#/components/parameters/Uuid'
      responses:
        "200":
          description: Cobrança
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  data:
                    type: object
                    properties:
                      uuid: { type: string, format: uuid }
                      amount: { type: string, example: "49.90" }
                      fee: { type: string }
                      amount_net: { type: string }
                      type: { type: string, enum: [pix, credit] }
                      status: { $ref: '#/components/schemas/TransactionStatus' }
                      created_at: { type: string, format: date-time }
                      updated_at: { type: string, format: date-time }
                      card:
                        type: object
                        properties:
                          brand: { type: string }
                          last4: { type: string }
                          installments: { type: integer }
                          refunded_amount: { type: number }
                      release_schedule:
                        type: array
                        items: { $ref: '#/components/schemas/Installment' }
                      settlement:
                        type: object
                        properties:
                          asset: { type: string, example: USDT }
                          status: { type: string }
                          network: { type: string }
                          amount_usdt: { type: number }
                          tx_hash: { type: string }
        "404": { $ref: '#/components/responses/Error' }
  /payments/{uuid}/refund:
    post:
      tags: [Cartão]
      summary: Estornar venda no cartão (total ou parcial)
      operationId: refundCard
      parameters:
        - $ref: '#/components/parameters/Uuid'
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                amount: { type: number, description: Valor a estornar. Sem ele, estorno total. }
      responses:
        "200":
          description: Estorno feito
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  data:
                    type: object
                    properties:
                      transaction_uuid: { type: string, format: uuid }
                      refunded_amount: { type: number }
                      full: { type: boolean }
                      status: { $ref: '#/components/schemas/TransactionStatus' }
        "400": { $ref: '#/components/responses/Error' }
        "422": { $ref: '#/components/responses/Error' }
  /transactions:
    get:
      tags: [Consultas]
      summary: Listar transações
      operationId: listTransactions
      parameters:
        - { name: status, in: query, schema: { $ref: '#/components/schemas/TransactionStatus' } }
        - { name: type, in: query, schema: { type: string, enum: [pix, credit] } }
        - { name: start_date, in: query, schema: { type: string, format: date } }
        - { name: end_date, in: query, schema: { type: string, format: date } }
        - { name: page, in: query, schema: { type: integer, minimum: 1, default: 1 } }
        - { name: per_page, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 20 } }
      responses:
        "200":
          description: Página de transações
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  data:
                    type: array
                    items: { $ref: '#/components/schemas/Transaction' }
                  pagination:
                    type: object
                    properties:
                      current_page: { type: integer }
                      last_page: { type: integer }
                      per_page: { type: integer }
                      total: { type: integer }
        "422": { $ref: '#/components/responses/ValidationError' }
  /transactions/{uuid}:
    get:
      tags: [Consultas]
      summary: Consultar transação
      operationId: getTransaction
      parameters:
        - $ref: '#/components/parameters/Uuid'
      responses:
        "200":
          description: Transação
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  data: { $ref: '#/components/schemas/Transaction' }
        "404": { $ref: '#/components/responses/Error' }
  /cashout/pix:
    post:
      tags: [Saques]
      summary: Saque via Pix
      description: |
        `amount` é o valor líquido que chega na chave; a taxa é somada e debitada do saldo.
        No modo automático da credencial, a chamada precisa vir de um IP cadastrado e com X-Client-ID.
      operationId: createCashout
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [amount, pix_key]
              properties:
                amount: { type: number, format: float, example: 150.00 }
                pix_key: { type: string, minLength: 10, example: maria@exemplo.com }
      responses:
        "200":
          description: Saque criado
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  message: { type: string }
                  withdrawal:
                    type: object
                    properties:
                      id: { type: integer }
                      amount: { type: number }
                      amount_gross: { type: number }
                      fee: { type: number }
                      status: { type: string, enum: [pending, processing, paid, rejected, failed, cancelled] }
                      pix_key: { type: string }
        "400": { $ref: '#/components/responses/Error' }
        "403": { $ref: '#/components/responses/Error' }
        "422": { $ref: '#/components/responses/ValidationError' }
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
    clientId:
      type: apiKey
      in: header
      name: X-Client-ID
  parameters:
    Uuid:
      name: uuid
      in: path
      required: true
      schema: { type: string, format: uuid }
  responses:
    Error:
      description: Erro
      content:
        application/json:
          schema:
            type: object
            properties:
              success: { type: boolean, example: false }
              message: { type: string }
    ValidationError:
      description: Campos inválidos
      content:
        application/json:
          schema:
            type: object
            properties:
              success: { type: boolean, example: false }
              message: { type: string }
              errors:
                type: object
                additionalProperties:
                  type: array
                  items: { type: string }
  schemas:
    TransactionStatus:
      type: string
      enum: [pending, waiting_payment, processing, completed, failed, cancelled, refunded, chargeback, mediation]
    PixRequest:
      type: object
      required: [amount, payer_name, payer_email, payer_cpf]
      properties:
        amount: { type: number, format: float, minimum: 0.01 }
        payer_name: { type: string, maxLength: 255 }
        payer_email: { type: string, format: email }
        payer_cpf: { type: string, maxLength: 14, description: CPF ou CNPJ }
        description: { type: string, maxLength: 500 }
        settlement: { type: string, enum: [brl, usdt], default: brl }
        splits:
          type: array
          items:
            type: object
            required: [email, percentage]
            properties:
              email: { type: string, format: email }
              percentage: { type: number, minimum: 0.01, maximum: 100 }
    PixCharge:
      type: object
      properties:
        transaction_uuid: { type: string, format: uuid }
        amount: { type: number }
        fee: { type: number }
        amount_net: { type: number }
        status: { $ref: '#/components/schemas/TransactionStatus' }
        qr_code: { type: string, description: Pix copia e cola (EMV) }
        pix_code: { type: string, description: Igual a qr_code }
        qr_code_base64: { type: string, description: 'Imagem do QR Code (data:image/svg+xml;base64,...)' }
        expires_at: { type: string, format: date-time }
        expires_in_seconds: { type: integer }
        settlement: { type: string, enum: [brl, usdt] }
    CardRequest:
      type: object
      required: [amount, card, payer_name]
      properties:
        amount: { type: number, minimum: 1 }
        installments: { type: integer, minimum: 1, maximum: 12, default: 1 }
        card:
          type: object
          required: [number, holder, expiration, cvv]
          properties:
            number: { type: string, example: "4111111111111111" }
            holder: { type: string }
            expiration: { type: string, example: 12/2030 }
            cvv: { type: string, example: "123" }
        payer_name: { type: string }
        payer_email: { type: string, format: email }
        payer_cpf: { type: string }
        payer_phone: { type: string }
        billing:
          type: object
          properties:
            zipcode: { type: string }
            street: { type: string }
            number: { type: string }
            city: { type: string }
            state: { type: string, minLength: 2, maxLength: 2 }
        description: { type: string }
        three_ds: { type: string, enum: [none, auto, required] }
        return_url: { type: string, format: uri }
    CardResult:
      type: object
      properties:
        success: { type: boolean }
        message: { type: string }
        data:
          type: object
          properties:
            transaction_uuid: { type: string, format: uuid }
            status: { type: string, enum: [approved, requires_authentication, processing, declined, failed] }
            amount: { type: number }
            fee: { type: number }
            amount_net: { type: number }
            installments: { type: integer }
            card:
              type: object
              properties:
                brand: { type: string }
                last4: { type: string }
            authentication_url: { type: string, format: uri }
            decline:
              type: object
              properties:
                code: { type: string }
                message: { type: string }
                retryable: { type: boolean }
            release_schedule:
              type: array
              items: { $ref: '#/components/schemas/Installment' }
    Installment:
      type: object
      properties:
        installment: { type: integer }
        amount: { type: number }
        date: { type: string, format: date }
        status: { type: string }
    Transaction:
      type: object
      properties:
        uuid: { type: string, format: uuid }
        transaction_uuid: { type: string, format: uuid }
        amount: { type: number }
        amount_gross: { type: number }
        amount_net: { type: number }
        fee: { type: number }
        type: { type: string, enum: [pix, credit] }
        payment_method: { type: string, enum: [pix, credit_card] }
        status: { $ref: '#/components/schemas/TransactionStatus' }
        settlement: { type: string, enum: [brl, usdt] }
        description: { type: string }
        external_id: { type: string }
        payer:
          type: object
          properties:
            name: { type: string }
            email: { type: string }
            document: { type: string }
        created_at: { type: string, format: date-time }
        paid_at: { type: string, format: date-time }
    WebhookEvent:
      type: object
      description: Corpo enviado para a sua URL de webhook.
      properties:
        id: { type: string, format: uuid, description: Igual em todas as tentativas de entrega }
        event:
          type: string
          enum:
            - deposit.completed
            - transaction.waiting_payment
            - transaction.failed
            - transaction.refunded
            - transaction.chargeback
            - transaction.completed
            - withdrawal.pending
            - withdrawal.completed
            - withdrawal.failed
            - pix_payment.pending
            - pix_payment.completed
            - pix_payment.failed
            - crypto_settlement.completed
            - crypto_settlement.failed
            - checkout.order_paid
        data: { type: object }
        created_at: { type: string, format: date-time }
