> ## Documentation Index
> Fetch the complete documentation index at: https://docs.troqpay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Criar checkout Pix

> Cria um checkout Pix em BRL e retorna os dados necessários para exibir o pagamento ao comprador. Devolve `201 Created` na primeira criação e `200 OK` em reentrega idempotente (mesma `Idempotency-Key`, mesmo corpo).



## OpenAPI

````yaml /api-reference/openapi.json post /v1/checkouts
openapi: 3.1.0
info:
  title: TroqPay API
  description: >-
    API da TroqPay para criar cobranças Pix, ler saldo, solicitar saques em
    produção e processar eventos por webhook.
  version: 1.0.0
servers:
  - url: https://api.troqpay.com
    description: >-
      Use a mesma URL-base para teste e produção. O ambiente é definido pela
      chave utilizada (`trq_test_` ou `trq_live_`).
security:
  - bearerAuth: []
tags:
  - name: Checkouts
    description: Criação e consulta de cobranças Pix.
  - name: Payment Links
    description: >-
      Criação, listagem e consulta de links de pagamento a partir de produtos
      cadastrados.
  - name: Saldo
    description: >-
      Leitura do saldo agregado da conta TroqPay (valores em decimal, todos em
      BRL).
  - name: Saques
    description: Criação e consulta de saques em produção.
  - name: Webhooks
    description: Eventos enviados pela TroqPay quando um checkout muda de estado.
  - name: Status
    description: Endpoints públicos para verificar disponibilidade da API.
paths:
  /v1/checkouts:
    post:
      tags:
        - Checkouts
      summary: Criar checkout Pix
      description: >-
        Cria um checkout Pix em BRL e retorna os dados necessários para exibir o
        pagamento ao comprador. Devolve `201 Created` na primeira criação e `200
        OK` em reentrega idempotente (mesma `Idempotency-Key`, mesmo corpo).
      operationId: createCheckout
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
        - $ref: '#/components/parameters/RequestIdHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckoutCreateRequest'
            examples:
              basic:
                summary: Checkout Pix em BRL
                value:
                  amount: 12990
                  description: Plano Pro
                  externalId: order_1001
                  expiresIn: 1800
                  customer:
                    name: Maria Silva
                    email: maria@example.com
                  metadata:
                    plan: pro
      responses:
        '200':
          description: >-
            Resposta idempotente: a mesma `Idempotency-Key` foi usada com o
            mesmo corpo. A API devolve o checkout já existente em vez de criar
            um novo.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestIdResponseHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Checkout'
        '201':
          description: Checkout criado com sucesso.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestIdResponseHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Checkout'
              examples:
                created:
                  summary: Checkout criado e aguardando pagamento
                  value:
                    id: chk_4a8b3c1d5e6f2a9b0c1d
                    livemode: false
                    status: PENDING
                    amount: 12990
                    currency: BRL
                    description: Plano Pro
                    externalId: order_1001
                    checkoutUrl: https://pay.troqpay.com/pay/chk_4a8b3c1d5e6f2a9b0c1d
                    createdAt: '2026-04-25T14:00:00.000Z'
                    expiresAt: '2026-04-25T14:30:00.000Z'
                    paidAt: null
                    customer:
                      name: Maria Silva
                      email: maria@example.com
                      document: null
                    pix:
                      copyPaste: 00020101021226840014br.gov.bcb.pix...
                      qrCodeUrl: >-
                        https://api.openpix.com.br/openpix/charge/brcode/image/chk_4a8b3c1d5e6f2a9b0c1d.png
                    settlement:
                      currency: BRL
                      status: PENDING
                      amount: null
                    metadata:
                      plan: pro
        '400':
          description: Corpo inválido ou JSON malformado.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestIdResponseHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalidRequestBody:
                  summary: Falha de validação no corpo
                  value:
                    error:
                      type: validation_error
                      code: invalid_request_body
                      message: Number must be greater than 0
                      requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
                invalidJson:
                  summary: JSON malformado
                  value:
                    error:
                      type: validation_error
                      code: invalid_json
                      message: request body must be valid JSON
                      requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: >-
            Conta sem acesso a produção ou chave sem permissão para criar
            checkouts.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestIdResponseHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                forbidden:
                  summary: Chave LIVE em conta não aprovada
                  value:
                    error:
                      type: auth_error
                      code: forbidden
                      message: API key does not have access to live-mode checkouts
                      requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
                missingPermission:
                  summary: Chave sem permissão de criação de checkout
                  value:
                    error:
                      type: auth_error
                      code: api_key_scope_forbidden
                      message: >-
                        API key does not have permission to access this
                        resource.
                      requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
        '409':
          description: Conflito de idempotência.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestIdResponseHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                idempotencyConflict:
                  summary: Mesma Idempotency-Key, corpo diferente
                  value:
                    error:
                      type: conflict_error
                      code: idempotency_conflict
                      message: >-
                        Idempotency-Key already used with a different request
                        body
                      requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
        '422':
          description: Regra de negócio não atendida.
          headers:
            Request-Id:
              $ref: '#/components/headers/RequestIdResponseHeader'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                invalidExpiresIn:
                  summary: expiresIn fora do intervalo
                  value:
                    error:
                      type: business_error
                      code: invalid_expires_in
                      message: expiresIn must be between 900 and 86400 seconds
                      requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/ProviderUnavailable'
      x-codeSamples:
        - lang: cURL
          label: cURL
          source: |-
            curl -X POST https://api.troqpay.com/v1/checkouts \
              -H "Authorization: Bearer trq_test_xxx" \
              -H "Content-Type: application/json" \
              -H "Idempotency-Key: order_1001" \
              -d '{
                "amount": 12990,
                "description": "Plano Pro",
                "externalId": "order_1001",
                "expiresIn": 1800,
                "customer": {
                  "name": "Maria Silva",
                  "email": "maria@example.com"
                },
                "metadata": {
                  "plan": "pro"
                }
              }'
        - lang: JavaScript
          label: JavaScript
          source: >-
            const response = await fetch("https://api.troqpay.com/v1/checkouts",
            {
              method: "POST",
              headers: {
                "Authorization": "Bearer trq_test_xxx",
                "Content-Type": "application/json",
                "Idempotency-Key": "order_1001"
              },
              body: JSON.stringify({
                amount: 12990,
                description: "Plano Pro",
                externalId: "order_1001",
                expiresIn: 1800,
                customer: { name: "Maria Silva", email: "maria@example.com" },
                metadata: { plan: "pro" }
              })
            });


            const checkout = await response.json();
components:
  parameters:
    IdempotencyKeyHeader:
      name: Idempotency-Key
      in: header
      required: false
      description: >-
        Chave de idempotência opcional. A API normaliza o corpo da requisição
        com uma serialização JSON estável e key-sorted, então reordenar chaves
        equivale ao mesmo corpo. O valor é trimado; uma string vazia após o trim
        equivale a não enviar a chave (sem erro, mas sem deduplicação). A chave
        permanece associada ao recurso indefinidamente — não há expiração.
        Primeira criação devolve `201`; reentrega idempotente devolve `200`.
      schema:
        type: string
        example: order_1001
    RequestIdHeader:
      name: Request-Id
      in: header
      required: false
      description: >-
        Identificador opcional fornecido pelo cliente para correlação. A API
        aceita também `X-Request-Id`. O valor é ecoado de volta no header de
        resposta `Request-Id`. Se nenhum dos dois é enviado, a API gera `req_<24
        hex>`.
      schema:
        type: string
        example: req_4a8b3c1d5e6f2a9b0c1d2e3f
  schemas:
    CheckoutCreateRequest:
      type: object
      required:
        - amount
      description: Payload para criação de um checkout Pix.
      properties:
        amount:
          type: integer
          minimum: 100
          example: 12990
          description: Valor em centavos de BRL. Mínimo de 100 centavos (R$ 1,00).
        currency:
          type: string
          description: Moeda da cobrança. Hoje, sempre `BRL`.
          enum:
            - BRL
          default: BRL
        description:
          type: string
          minLength: 1
          maxLength: 255
          description: Texto livre de 1 a 255 caracteres para identificar a cobrança.
          example: Plano Pro
        externalId:
          type: string
          minLength: 1
          maxLength: 255
          description: Identificador do pedido no seu sistema, 1 a 255 caracteres.
          example: order_1001
        expiresIn:
          type: integer
          minimum: 900
          maximum: 86400
          default: 1800
          example: 1800
          description: >-
            Tempo de expiração da cobrança em segundos. Entre 900 e 86400. O
            padrão é 1800 (30 minutos).
        customer:
          $ref: '#/components/schemas/CustomerInput'
        metadata:
          type: object
          description: Pares chave-valor livres. Apenas valores `string` são aceitos.
          additionalProperties:
            type: string
          example:
            plan: pro
    Checkout:
      type: object
      required:
        - id
        - livemode
        - status
        - amount
        - currency
        - checkoutUrl
        - createdAt
        - expiresAt
        - pix
        - settlement
        - metadata
      description: >-
        Objeto principal da API de cobranças. Reúne os dados da cobrança Pix, do
        pagamento e da liquidação.
      properties:
        id:
          type: string
          description: >-
            Identificador técnico do checkout. Formato `chk_` + 20 caracteres
            hex.
          example: chk_4a8b3c1d5e6f2a9b0c1d
        livemode:
          type: boolean
          description: '`true` para chaves `trq_live_`; `false` para `trq_test_`.'
          example: false
        status:
          $ref: '#/components/schemas/CheckoutStatus'
        amount:
          type: integer
          description: Valor da cobrança em centavos de BRL.
          example: 12990
        currency:
          type: string
          description: Moeda da cobrança. Hoje, sempre `BRL`.
          enum:
            - BRL
          example: BRL
        description:
          type:
            - string
            - 'null'
          description: O texto livre que você enviou na criação.
          example: Plano Pro
        externalId:
          type:
            - string
            - 'null'
          description: O ID do pedido no seu sistema.
          example: order_1001
        checkoutUrl:
          type: string
          format: uri
          description: >-
            URL canônica do checkout hospedado pela TroqPay
            (`/pay/{checkoutId}`).
          example: https://pay.troqpay.com/pay/chk_4a8b3c1d5e6f2a9b0c1d
        createdAt:
          type: string
          format: date-time
          description: Quando o checkout foi criado.
        expiresAt:
          type: string
          format: date-time
          description: Quando o checkout expira (se ainda não foi pago).
        paidAt:
          type:
            - string
            - 'null'
          format: date-time
          description: Preenchido quando `status` muda para `PAID`.
        customer:
          description: >-
            Dados do comprador. O campo `phone` aceito no envio **não** é
            retornado aqui.
          anyOf:
            - $ref: '#/components/schemas/Customer'
            - type: 'null'
        pix:
          $ref: '#/components/schemas/PixDetails'
        settlement:
          $ref: '#/components/schemas/Settlement'
        metadata:
          type: object
          description: >-
            Os pares chave-valor que você enviou. Pode ser `{}` se nenhum foi
            enviado.
          additionalProperties:
            type: string
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/ErrorBody'
    CustomerInput:
      type: object
      required:
        - name
      description: >-
        Dados do comprador no envio do checkout. Quando enviado, é obrigatório
        informar `name` e pelo menos um de `email`, `document` ou `phone`.
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
          description: Nome do comprador.
          example: Maria Silva
        email:
          type: string
          format: email
          description: Email do comprador.
          example: maria@example.com
        document:
          type: string
          minLength: 3
          maxLength: 32
          description: >-
            Documento do comprador (CPF, CNPJ ou outro). Aceito como string de 3
            a 32 caracteres; a API não valida o formato.
          example: '12345678900'
        phone:
          type: string
          minLength: 8
          maxLength: 32
          description: >-
            Telefone do comprador. Aceito apenas no envio; a resposta do
            checkout (e o webhook) não retornam este campo.
          example: '+5511987654321'
    CheckoutStatus:
      type: string
      description: Estado atual da cobrança.
      enum:
        - PENDING
        - PAID
        - REFUNDED
        - EXPIRED
        - CANCELLED
    Customer:
      type: object
      description: >-
        Dados do comprador retornados pela API. O campo `phone` aceito no envio
        **não** é retornado neste objeto.
      properties:
        name:
          type: string
          description: Nome do comprador.
          example: Maria Silva
        email:
          type:
            - string
            - 'null'
          format: email
          description: Email do comprador, quando enviado.
          example: maria@example.com
        document:
          type:
            - string
            - 'null'
          description: Documento do comprador, quando enviado.
          example: '12345678900'
    PixDetails:
      type: object
      required:
        - copyPaste
        - qrCodeUrl
      description: Dados necessários para exibir o Pix ao comprador.
      properties:
        copyPaste:
          type: string
          description: Linha do Pix copia e cola.
          example: 00020101021226840014br.gov.bcb.pix...
        qrCodeUrl:
          type: string
          format: uri
          description: >-
            URL da imagem do QR Code do Pix, hospedada pelo provedor de
            pagamento. Trate o valor como opaco — o formato e o domínio podem
            variar.
          example: >-
            https://api.openpix.com.br/openpix/charge/brcode/image/chk_4a8b3c1d5e6f2a9b0c1d.png
    Settlement:
      type: object
      required:
        - currency
        - status
      description: Dados da liquidação do checkout, em BRL.
      properties:
        currency:
          type: string
          description: Moeda de liquidação aplicada ao checkout. Hoje, sempre `BRL`.
          enum:
            - BRL
          example: BRL
        status:
          $ref: '#/components/schemas/SettlementStatus'
        amount:
          type:
            - string
            - 'null'
          example: '129.90'
          description: Valor de liquidação em BRL como string decimal.
    ErrorBody:
      type: object
      required:
        - type
        - code
        - message
        - requestId
      description: >-
        Corpo padronizado de erro da API. As mensagens em `message` chegam em
        inglês — é o que a API emite literalmente.
      properties:
        type:
          type: string
          description: Categoria do erro.
          enum:
            - auth_error
            - validation_error
            - business_error
            - not_found_error
            - conflict_error
            - provider_error
            - rate_limit_error
            - internal_error
          example: validation_error
        code:
          type: string
          description: Código estável para tratar a falha no seu backend.
          example: invalid_request_body
        message:
          type: string
          description: Mensagem legível do erro (em inglês, literal).
          example: Number must be greater than 0
        requestId:
          type: string
          description: Identificador da requisição para logs e investigação.
          example: req_4a8b3c1d5e6f2a9b0c1d2e3f
    SettlementStatus:
      type: string
      description: >-
        Estado da liquidação. `COMPLETED` é reservado para uso futuro e não é
        emitido atualmente.
      enum:
        - PENDING
        - AVAILABLE
        - COMPLETED
  headers:
    RequestIdResponseHeader:
      description: >-
        Identificador da requisição. Sempre presente. Ecoa o valor enviado em
        `Request-Id` ou `X-Request-Id`, ou um identificador gerado pela API no
        formato `req_<24 hex>`.
      schema:
        type: string
        example: req_4a8b3c1d5e6f2a9b0c1d2e3f
  responses:
    Unauthorized:
      description: >-
        Chave ausente, mal formatada, inválida ou revogada. A API sempre devolve
        `code: "unauthorized"` em 401.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestIdResponseHeader'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            unauthorized:
              summary: Bearer ausente ou inválido
              value:
                error:
                  type: auth_error
                  code: unauthorized
                  message: invalid or missing bearer token
                  requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
    RateLimited:
      description: Limite de requisições excedido. Faça retry com backoff.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestIdResponseHeader'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            rateLimited:
              summary: Limite excedido
              value:
                error:
                  type: rate_limit_error
                  code: rate_limit_exceeded
                  message: Too many requests. Please retry with backoff.
                  requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
    ProviderUnavailable:
      description: >-
        Provedor temporariamente indisponível. Faça retry — não é problema do
        payload.
      headers:
        Request-Id:
          $ref: '#/components/headers/RequestIdResponseHeader'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            providerUnavailable:
              summary: Provedor indisponível
              value:
                error:
                  type: provider_error
                  code: provider_unavailable
                  message: Provider is currently unavailable.
                  requestId: req_4a8b3c1d5e6f2a9b0c1d2e3f
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key

````