openapi: 3.0.3
info:
  title: Pangeia PAY API
  version: "1.0.4"
  description: >
    Documentacao publica da API de cobranca/recebimento do Pangeia PAY.
    Este documento inclui apenas endpoints de integracao de pagamentos e
    o contrato do payload de IPN enviado ao endpoint do lojista.
servers:
  - url: https://pay.pangeialabs.com
    description: Producao
  - url: http://localhost:5000
    description: Desenvolvimento local
tags:
  - name: Payments
  - name: PublicAuth
  - name: PublicDocs
components:
  schemas:
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
    RegistrarRequest:
      type: object
      required: [buyer_name, buyer_taxid, order_amount, order_id, api_key]
      properties:
        buyer_name: { type: string, example: "Joao da Silva" }
        buyer_taxid: { type: string, example: "12345678901" }
        order_amount: { type: number, format: float, example: 149.9 }
        order_id: { type: string, example: "PED-10001" }
        api_key: { type: string, example: "ab12cd34..." }
        buyer_email: { type: string, example: "comprador@email.com" }
        buyer_mobile: { type: string, example: "+5511999999999" }
        billing_address: { type: string }
        shipping_address: { type: string }
        coupon_code: { type: string }
        discount: { type: number, format: float }
        shipping_total: { type: number, format: float }
        tax_total: { type: number, format: float }
        redirect_url: { type: string, format: uri, example: "https://seusite.com/retorno" }
        refund_address: { type: string, description: "Endereco de troco/reembolso para cripto" }
        crypto_confirmations: { type: integer, minimum: 1, example: 6 }
        crypto_agio_percent: { type: number, format: float, example: 2.0 }
    RegistrarPixResponse:
      type: object
      properties:
        order_id: { type: string }
        order_status: { type: string, example: pending }
        payment_method: { type: string, example: pix }
        allowed_payment_methods:
          type: array
          items: { type: string }
          example: [pix, bitcoin, outracoin]
        order_group_id:
          type: string
          description: "Presente quando a cobranca foi registrada com multiplos metodos."
        unique_amount: { type: number, format: float }
        unique_id: { type: string, description: "ObjectId em string" }
        url: { type: string, format: uri }
        checkout_options:
          type: array
          items:
            type: object
            properties:
              payment_method: { type: string }
              unique_id: { type: string }
              url: { type: string, format: uri }
        pixcode: { type: string }
        qrcode: { type: string, description: "PNG base64 sem prefixo data:image" }
        checkout_quote_snapshot:
          type: object
          description: "Snapshot de cotacao no cadastro por metodo cripto ativo (quando houver)."
    RegistrarCryptoResponse:
      type: object
      properties:
        order_id: { type: string }
        order_status: { type: string, example: pending }
        payment_method: { type: string, enum: [bitcoin, outracoin] }
        allowed_payment_methods:
          type: array
          items: { type: string }
          example: [pix, bitcoin, outracoin]
        order_group_id:
          type: string
          description: "Presente quando a cobranca foi registrada com multiplos metodos."
        unique_amount: { type: number, format: float }
        unique_id: { type: string }
        url: { type: string, format: uri }
        checkout_options:
          type: array
          items:
            type: object
            properties:
              payment_method: { type: string }
              unique_id: { type: string }
              url: { type: string, format: uri }
        crypto_currency: { type: string }
        crypto_symbol: { type: string, example: BTC }
        crypto_address: { type: string }
        crypto_node_account_label: { type: string }
        crypto_quote_brl: { type: number, format: float }
        crypto_quote_brl_effective: { type: number, format: float }
        crypto_quote_source: { type: string }
        crypto_quote_fetched_on: { type: string, format: date-time }
        crypto_agio_percent: { type: number, format: float }
        crypto_required_base_amount: { type: number, format: float }
        crypto_required_amount: { type: number, format: float }
        crypto_confirmations_required: { type: integer }
        payment_uri: { type: string }
        qrcode: { type: string }
        checkout_quote_snapshot:
          type: object
          description: "Snapshot de cotacao no cadastro por metodo cripto ativo (quando houver)."
    StatusResponse:
      type: object
      properties:
        status:
          type: string
          enum: [pending, confirming, paid, canceled, processing, shipped, delivered, expired]
          example: pending
        translated: { type: string, example: "Aguardando Pagamento" }
        payment_method: { type: string, example: pix }
        requested_payment_method: { type: string, example: pix }
        status_source_unique_id: { type: string, example: "65f5b0b6c2ab1d8b8f6a1234" }
        redirect_url: { type: string, format: uri }
    AuthRequest:
      type: object
      required: [api_key, api_secret]
      properties:
        api_key: { type: string }
        api_secret: { type: string }
    AuthResponse:
      type: object
      properties:
        success: { type: boolean }
        key: { type: string }
    MerchantIpnPayload:
      type: object
      description: >
        Payload enviado pelo backend do Pangeia PAY para o endpoint `ipn_url`
        configurado na conta quando houver atualizacao de status relevante.
        Status possiveis em `order_status`: `pending`, `confirming`, `paid`,
        `canceled`, `processing`, `shipped`, `delivered`.
        A integracao deve aceitar qualquer transicao de status a qualquer
        momento (sem restricao de maquina de estados), incluindo cenarios
        como `paid -> canceled` e `canceled -> paid`.
        Eventos automaticos enviam principalmente `paid` (baixa PIX/cripto)
        e `canceled` (expiracao sem pagamento), mas qualquer status pode ser
        reenviado/alterado conforme operacao.
      required: [order_id, order_status, order_amount, unique_amount, ipn_secret]
      properties:
        order_id: { type: string, example: "PIXIA-1772489488-3468fc7e" }
        order_status:
          type: string
          enum: [pending, confirming, paid, canceled, processing, shipped, delivered]
          example: paid
        order_amount: { type: number, format: float, example: 10.0 }
        unique_amount: { type: number, format: float, example: 10.0 }
        ipn_secret:
          type: string
          description: "Mesmo secret configurado na conta; use para validar autenticidade."
        paid_on: { type: string, format: date-time, nullable: true }
        paid_with: { type: string, example: pix }
        redirect_url: { type: string, format: uri, nullable: true }
        description: { type: string, nullable: true }
paths:
  /apidoc/openapi.yaml:
    get:
      tags: [PublicDocs]
      summary: Arquivo OpenAPI oficial da plataforma
      responses:
        "200":
          description: Conteudo YAML
  /apidoc/examples:
    get:
      tags: [PublicDocs]
      summary: Arquivo markdown com exemplos praticos de uso da API
      responses:
        "200":
          description: Conteudo markdown
  /registrar:
    post:
      tags: [Payments]
      summary: Registra uma cobranca com metodos definidos pela conta
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/RegistrarRequest" }
      responses:
        "201":
          description: Cobranca registrada
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/RegistrarPixResponse"
                  - $ref: "#/components/schemas/RegistrarCryptoResponse"
        "400":
          description: Campos invalidos
        "403":
          description: Conta desativada ou sem metodo ativo
        "404":
          description: api_key nao encontrada
        "502":
          description: Falha cotacao/geracao endereco cripto
        "503":
          description: RPC cripto indisponivel
  /pixqrcode/{unique_id}:
    get:
      tags: [Payments]
      summary: Retorna payload e QRCode da cobranca
      parameters:
        - in: path
          name: unique_id
          required: true
          schema: { type: string }
      responses:
        "200":
          description: Payload retornado conforme metodo
        "400":
          description: ID invalido ou metodo nao suportado
        "404":
          description: Transacao/chave nao encontrada
  /status/{unique_id}:
    get:
      tags: [Payments]
      summary: Consulta status da cobranca
      description: >
        Retorna o status canônico da cobrança. O campo `status` pode retornar
        `expired` como estado derivado por tempo, quando a cobrança permanece
        `pending/confirming` além da janela de expiração.
      parameters:
        - in: path
          name: unique_id
          required: true
          schema: { type: string }
      responses:
        "200":
          description: Status atual
          content:
            application/json:
              schema: { $ref: "#/components/schemas/StatusResponse" }
        "400":
          description: ID invalido
        "404":
          description: Transacao invalida/inexistente
  /auth:
    post:
      tags: [PublicAuth]
      summary: Autenticacao por api_key + api_secret
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/AuthRequest" }
      responses:
        "200":
          description: Credenciais validas
          content:
            application/json:
              schema: { $ref: "#/components/schemas/AuthResponse" }
        "400":
          description: Credenciais ausentes
        "403":
          description: Credenciais invalidas
