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

# Criar venda rápida

> Cria uma cobrança individual com os itens no corpo e devolve a URL de pagamento pronta para enviar.

`POST /checkout/charges`

Faz parte do recurso [Vendas rápidas](/pt-BR/checkout/charges) — a relação com Link e Session está
lá.

Cria a compra com a configuração inline: itens, métodos, branding e splits vão no **topo** do corpo,
com o mesmo formato que o [Link](/pt-BR/checkout/links/create) aceita. A resposta é `201` com a
Session (`linkId: null`) e a `url` para você enviar pelo seu canal.

O objeto `customer` é opcional e serve para **pré-preencher** os dados na página — o comprador ainda
pode corrigi-los, e os `requiredFields` continuam valendo na confirmação.

<Warning>
  **`mode: "subscription"` é recusado com `400`.** Recorrência só nasce de um
  [Link de assinatura](/pt-BR/checkout/links#assinaturas-via-checkout).
</Warning>

<Warning>
  **`null` explícito é recusado aqui.** No Link, vários campos aceitam `null`; no corpo da venda
  rápida, não. Campo que você não vai usar deve ser **omitido**. É a diferença que mais derruba quem
  copia a configuração de um Link direto para cá — veja o `clean()` no exemplo abaixo.
</Warning>

<Warning>
  **Valores são inteiros em centavos**, e o split exige soma 100 com exatamente um `liable: true` —
  as mesmas regras do Link. Veja [Criar checkout link](/pt-BR/checkout/links/create).
</Warning>

<Info>
  Endpoint idempotente. Envie `Idempotency-Key` para que um retry por timeout não crie duas cobranças
  — sem ele, a segunda chamada gera outro `cs_` e outra URL. Veja
  [Convenções](/pt-BR/convencoes#idempot%C3%AAncia).
</Info>

## Exemplo

```bash theme={null}
curl -X POST https://api.sandbox.z2pay.com/v1/checkout/charges \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7" \
  -d '{
    "items": [{ "name": "Consultoria 1h", "quantity": 1, "unitAmount": 30000 }],
    "paymentMethods": { "pix": { "enabled": true } },
    "customer": { "name": "Cliente X", "email": "x@example.com" }
  }'
```

```json Resposta 201 theme={null}
{
  "id": "cs_50b0abc54b632e7c57de3a73815413ace1d545dcd16da95c",
  "linkId": null,
  "status": "created",
  "amount": 30000,
  "currency": "BRL",
  "customer": { "name": "Cliente X", "email": "x@example.com" },
  "transactionId": null,
  "createdAt": "2026-06-24T12:00:00.000Z",
  "expiresAt": "2026-06-25T12:00:00.000Z",
  "url": "https://pay.sandbox.z2pay.com/c/cs_50b0abc54b632e7c57de3a73815413ace1d545dcd16da95c"
}
```

***

## Espelhar a configuração de um Link

Já tem um Link com branding, métodos e splits ajustados e quer disparar uma cobrança individual
**com a mesma cara**, mas com outro carrinho? Leia o Link, mova o `config` para o topo do corpo e
poste aqui. É o mesmo caminho do "Duplicar como venda rápida" do painel.

<Info>
  A venda rápida resultante é **independente**: ela copia a configuração no momento da criação, não
  cria vínculo. Editar o Link depois não a alcança. Se você quer o vínculo vivo, compartilhe a URL do
  próprio Link.
</Info>

<Steps>
  <Step title="Leia o Link">
    [`GET /checkout/links/{id}`](/pt-BR/checkout/links/get). A resposta traz `items`,
    `paymentMethods`, `splits` e `branding` dentro de `config`; o resto já vem no topo.
  </Step>

  <Step title="Mova o config para o topo">
    Os quatro campos aninhados sobem um nível. `locale`, `currency`, `requiredFields`,
    `customFields`, `successUrl`, `cancelUrl`, `description`, `metadata` e `expirationMinutes` são
    copiados direto.
  </Step>

  <Step title="Troque o que é seu">
    `items` vem do **seu** carrinho, não do Link. Omita `name`, `slug` e qualquer configuração de
    assinatura. Envie `mode: "payment"`.
  </Step>

  <Step title="Poste">
    `POST /checkout/charges` → `201` com o `cs_` e a `url`.
  </Step>
</Steps>

<Warning>
  **Quatro coisas não atravessam:** `mode: "subscription"` e o objeto `subscription` (recusados);
  `name` e `slug` (são identidade do template); qualquer `null` (omita em vez de enviar); e
  `chargeType` `recurring`/`activation` nos itens — em pagamento único todo item é cobrança única.
</Warning>

```js theme={null}
const API = "https://api.sandbox.z2pay.com/v1";
const KEY = "SUA_CHAVE_DE_SANDBOX";

const link = await fetch(`${API}/checkout/links/${linkId}`, {
  headers: { "x-api-key": KEY },
}).then((r) => r.json());

const { paymentMethods, splits, branding } = link.config;

const body = clean({
  mode: "payment",
  currency: link.currency,
  locale: link.locale,
  items: [{ name: "Pedido #4821", quantity: 1, unitAmount: 34780 }],
  paymentMethods,
  splits,
  branding,
  requiredFields: link.requiredFields,
  customFields: link.customFields,
  successUrl: link.successUrl,
  cancelUrl: link.cancelUrl,
  description: link.description,
  metadata: link.metadata,
  expirationMinutes: link.expirationMinutes,
  customer: { email: "cliente@example.com" },
});

const charge = await fetch(`${API}/checkout/charges`, {
  method: "POST",
  headers: { "x-api-key": KEY, "Content-Type": "application/json" },
  body: JSON.stringify(body),
}).then((r) => r.json());

// Remove as chaves nulas: o corpo da venda rápida recusa `null` explícito.
function clean(obj) {
  return Object.fromEntries(Object.entries(obj).filter(([, v]) => v != null));
}
```

As URLs de mídia (`branding.logoUrl`, `faviconUrl`, `coverUrl` e `items[].imageUrl`) copiam
verbatim — são endereços públicos de CDN, sem novo upload.


## OpenAPI

````yaml openapi/checkout.json POST /checkout/charges
openapi: 3.0.3
info:
  title: Z2Pay Checkout API
  version: 1.0.0
  description: >-
    API pública dedicada do Checkout. Autenticação via header x-api-key com a
    API key unificada da conta (z2_{live|test}_{sk|pk}_...). Endpoints privados
    exigem uma key secret (sk); endpoints públicos aceitam a key publishable
    (pk) consumida pelo frontend do comprador.
servers:
  - url: https://api.sandbox.z2pay.com/v1
    description: Sandbox
  - url: https://api.z2pay.com/v1
    description: Produção
security: []
tags:
  - name: Checkout Links
    description: Checkout Links (integração API via sk_)
  - name: Checkout Sessions
    description: Checkout Sessions (integração API via sk_)
  - name: Vendas rápidas
    description: Cobrança individual sem Link — Sessions ad-hoc criadas com a chave secreta
paths:
  /checkout/charges:
    post:
      tags:
        - Vendas rápidas
      summary: Criar venda rápida
      description: >-
        Cria uma cobrança individual sem Link: a configuração vai inline no
        corpo e a resposta traz a URL de pagamento pronta para enviar ao
        cliente. Nada é cobrado aqui — quem paga é o comprador, abrindo a URL.
      operationId: CheckoutChargeApiController_create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  type: string
                  enum:
                    - payment
                    - subscription
                  default: payment
                  description: >-
                    Apenas 'payment' é aceito na venda rápida ad-hoc —
                    'subscription' é rejeitado (recorrência exige Link).
                currency:
                  type: string
                  enum:
                    - BRL
                  default: BRL
                  description: Moeda da cobrança. Só `BRL` — os gateways liquidam em real.
                locale:
                  type: string
                  enum:
                    - pt-BR
                    - en-US
                    - es-ES
                  default: pt-BR
                  description: Idioma do checkout (default 'pt-BR').
                items:
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                        minLength: 1
                        maxLength: 255
                        description: Nome do item exibido no checkout.
                      description:
                        type: string
                        maxLength: 2000
                        description: Descrição do item.
                      imageUrl:
                        type: string
                        format: uri
                        maxLength: 2000
                        description: URL da imagem do item.
                      quantity:
                        type: integer
                        minimum: 1
                        description: Quantidade do item (inteiro ≥ 1).
                      unitAmount:
                        type: integer
                        minimum: 1
                        description: Preço UNITÁRIO do item, em centavos (inteiro ≥ 1).
                      chargeType:
                        type: string
                        enum:
                          - one_time
                          - recurring
                          - activation
                        description: >-
                          Eixo de cobrança da linha: ausente/'one_time' em
                          pagamento único; 'recurring'/'activation' espelham
                          PlanItem.kind em mode=subscription.
                      metadata:
                        type: object
                        additionalProperties:
                          type: string
                        description: Metadados livres do item (string → string).
                    required:
                      - name
                      - quantity
                      - unitAmount
                  minItems: 1
                  description: >-
                    Itens da cobrança (unitAmount em centavos); ao menos 1 é
                    obrigatório.
                paymentMethods:
                  type: object
                  properties:
                    card:
                      type: object
                      properties:
                        enabled:
                          type: boolean
                        installments:
                          type: object
                          properties:
                            maxInstallments:
                              type: integer
                              minimum: 1
                              maximum: 12
                            freeInstallments:
                              type: integer
                              minimum: 0
                              maximum: 12
                            interestRate:
                              type: number
                              minimum: 0
                              maximum: 100
                            interestType:
                              type: string
                              enum:
                                - simple
                                - compound
                              default: compound
                          required:
                            - maxInstallments
                        threeDSecure:
                          type: boolean
                          description: >-
                            Liga a autenticação 3D Secure para os pagamentos com
                            cartão deste checkout. Aceita `true` ou `false`;
                            default `false` (sem desafio). Exige 3DS habilitado
                            para a conta — sem a habilitação o campo é aceito e
                            ignorado (nenhum erro, nenhum desafio); se a conta
                            for habilitada depois, os checkouts com `true`
                            passam a desafiar automaticamente.
                      required:
                        - enabled
                    pix:
                      type: object
                      properties:
                        enabled:
                          type: boolean
                        expiresIn:
                          type: integer
                          minimum: 60
                          maximum: 86400
                      required:
                        - enabled
                    boleto:
                      type: object
                      properties:
                        enabled:
                          type: boolean
                        dueDateDays:
                          type: integer
                          minimum: 1
                          maximum: 30
                      required:
                        - enabled
                    combined:
                      type: object
                      properties:
                        enabled:
                          type: boolean
                        minAmountPerPayment:
                          type: integer
                          minimum: 1
                        maxPaymentsCount:
                          type: integer
                          minimum: 2
                          maximum: 8
                      required:
                        - enabled
                  description: >-
                    Métodos de pagamento habilitados (card/pix/boleto/combined);
                    ao menos um enabled.
                splits:
                  type: array
                  items:
                    type: object
                    properties:
                      recipientId:
                        type: string
                        minLength: 1
                        description: Recebedor (`rec_`) que fica com esta fatia.
                      percentage:
                        type: number
                        minimum: 0.01
                        maximum: 100
                        description: >-
                          Fatia do valor total, em porcentagem. Aceita decimais
                          (`33.33`).
                      liable:
                        type: boolean
                        description: >-
                          Marca o recebedor como responsável por chargebacks.
                          Exatamente um split do array precisa ter `true` —
                          nenhum ou mais de um é recusado.
                    required:
                      - recipientId
                      - percentage
                  description: >-
                    Divisão de receita por percentual; a soma deve ser
                    exatamente 100.
                branding:
                  type: object
                  properties:
                    primaryColor:
                      type: string
                      pattern: ^#([0-9a-f]{6}|[0-9a-f]{3})$
                      description: 'Cor primária do checkout em hex (#RRGGBB ou #RGB).'
                    logoUrl:
                      type: string
                      format: uri
                      maxLength: 2000
                      description: URL do logo exibido no checkout.
                    merchantName:
                      type: string
                      maxLength: 100
                      description: Nome do vendedor exibido no checkout (≤ 100 chars).
                    mobileLayout:
                      type: string
                      enum:
                        - single-page
                        - step-by-step
                      description: 'Layout no mobile: ''single-page'' ou ''step-by-step''.'
                    faviconUrl:
                      type: string
                      format: uri
                      maxLength: 2000
                      description: URL do favicon da página de checkout.
                    coverUrl:
                      type: string
                      format: uri
                      maxLength: 2000
                      description: URL da imagem de capa do checkout.
                  description: Customização visual do checkout.
                customer:
                  type: object
                  properties:
                    name:
                      type: string
                      maxLength: 255
                      description: Nome completo do cliente.
                    email:
                      type: string
                      format: email
                      maxLength: 255
                      description: E-mail do cliente.
                    document:
                      type: string
                      minLength: 6
                      maxLength: 30
                      description: Documento do cliente (CPF ou CNPJ, somente dígitos).
                    documentType:
                      type: string
                      enum:
                        - cpf
                        - cnpj
                        - passport
                      description: 'Tipo do documento do cliente: cpf ou cnpj.'
                    phone:
                      type: string
                      maxLength: 30
                      description: >-
                        Telefone do cliente (formato E.164, ex.:
                        +5511987654321).
                    address:
                      type: object
                      properties:
                        zipCode:
                          type: string
                          minLength: 3
                          maxLength: 20
                          description: CEP / código postal (somente dígitos).
                        street:
                          type: string
                          maxLength: 255
                          description: Logradouro (rua, avenida).
                        number:
                          type: string
                          maxLength: 20
                          description: Número do endereço.
                        complement:
                          type: string
                          maxLength: 255
                          description: Complemento do endereço (apartamento, bloco, sala).
                        neighborhood:
                          type: string
                          maxLength: 100
                          description: Bairro.
                        city:
                          type: string
                          maxLength: 100
                          description: Cidade.
                        state:
                          type: string
                          maxLength: 100
                          description: 'Estado ou UF (ex.: SP).'
                        country:
                          type: string
                          default: BR
                          description: 'País (código ISO 3166-1 alfa-2, ex.: BR).'
                  description: Pré-preenchimento dos dados do comprador.
                requiredFields:
                  type: array
                  items:
                    type: string
                    enum:
                      - email
                      - document
                      - phone
                      - address
                  description: >-
                    Campos do comprador exigidos no checkout (email, document,
                    phone, address).
                customFields:
                  type: array
                  items:
                    type: object
                    properties:
                      key:
                        type: string
                        pattern: ^[a-z][a-z0-9_]*$
                        maxLength: 50
                      label:
                        oneOf:
                          - type: string
                            minLength: 1
                            maxLength: 200
                          - type: object
                            additionalProperties:
                              type: string
                              minLength: 1
                              maxLength: 200
                      type:
                        type: string
                        enum:
                          - text
                          - select
                          - checkbox
                      options:
                        type: array
                        items:
                          oneOf:
                            - type: string
                              maxLength: 100
                            - type: object
                              properties:
                                value:
                                  type: string
                                  maxLength: 100
                                label:
                                  oneOf:
                                    - type: string
                                      minLength: 1
                                      maxLength: 200
                                    - type: object
                                      additionalProperties:
                                        type: string
                                        minLength: 1
                                        maxLength: 200
                              required:
                                - value
                                - label
                      required:
                        type: boolean
                    required:
                      - key
                      - label
                      - type
                  maxItems: 20
                  description: Campos customizados do formulário (máx. 20).
                successUrl:
                  type: string
                  format: uri
                  maxLength: 2000
                  description: URL de redirecionamento após pagamento aprovado.
                cancelUrl:
                  type: string
                  format: uri
                  maxLength: 2000
                  description: URL de redirecionamento quando o comprador cancela.
                description:
                  type: string
                  maxLength: 2000
                  description: Descrição da venda rápida (exibida na listagem).
                metadata:
                  type: object
                  additionalProperties:
                    type: string
                  description: >-
                    Metadados do seller (string → string); propagados ao
                    additionalInfo da Transaction e dos webhooks.
                expirationMinutes:
                  type: integer
                  minimum: 5
                  maximum: 43200
                  description: Expiração da sessão em minutos (5 a 43200 = 30 dias).
              required:
                - items
                - paymentMethods
      responses:
        '201':
          description: Venda rápida criada
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: Identificador único do registro.
                  linkId:
                    type: string
                    nullable: true
                    description: >-
                      Identificador do link de checkout que originou o registro;
                      nulo em sessões ad-hoc.
                  status:
                    type: string
                    description: Estado atual do registro.
                  mode:
                    type: string
                    description: >-
                      Modo do checkout: 'payment' (pagamento único) ou
                      'subscription' (assinatura).
                  currency:
                    type: string
                    description: 'Moeda no padrão ISO 4217 (ex.: BRL).'
                  locale:
                    type: string
                    description: 'Idioma do checkout (ex.: pt-BR, en-US, es-ES).'
                  config:
                    type: object
                    description: >-
                      Snapshot da configuração do checkout (formas de pagamento,
                      itens e personalização visual).
                  customer:
                    type: object
                    nullable: true
                    description: >-
                      Dados do comprador (nome, e-mail, documento e demais
                      informações).
                  customFieldValues:
                    type: object
                    nullable: true
                    description: >-
                      Valores preenchidos nos campos personalizados, indexados
                      pela key de cada campo.
                  paymentMethodSelected:
                    type: string
                    nullable: true
                    description: >-
                      Forma de pagamento selecionada pelo comprador na sessão
                      (ex.: credit_card, pix, boleto).
                  subtotal:
                    type: integer
                    description: Soma dos itens antes dos descontos, em centavos.
                  discountTotal:
                    type: integer
                    description: Total de descontos aplicados, em centavos.
                  amount:
                    type: integer
                    description: Valor total a ser cobrado, em centavos.
                  discounts:
                    type: array
                    items:
                      type: object
                    nullable: true
                    description: Descontos aplicados ao valor da sessão.
                  paymentAttempts:
                    type: integer
                    description: >-
                      Quantidade de tentativas de pagamento realizadas na
                      sessão.
                  transactionId:
                    type: string
                    nullable: true
                    description: >-
                      Identificador da transação gerada pelo pagamento da
                      sessão; nulo até haver pagamento.
                  subscriptionId:
                    type: string
                    nullable: true
                    description: >-
                      Identificador da assinatura criada a partir da sessão;
                      nulo até a ativação.
                  metadata:
                    type: object
                    nullable: true
                    description: >-
                      Metadados livres (pares chave-valor) para uso do
                      integrador; não afeta o processamento.
                  createdAt:
                    type: string
                    format: date-time
                    description: Data e hora de criação do registro (ISO 8601).
                  updatedAt:
                    type: string
                    format: date-time
                    description: Data e hora da última atualização do registro (ISO 8601).
                  openedAt:
                    type: string
                    format: date-time
                    nullable: true
                    description: >-
                      Data e hora em que a sessão foi aberta pelo comprador (ISO
                      8601); nula se ainda não aberta.
                  paidAt:
                    type: string
                    format: date-time
                    nullable: true
                    description: >-
                      Data e hora em que o pagamento foi confirmado (ISO 8601);
                      nula se não pago.
                  canceledAt:
                    type: string
                    format: date-time
                    nullable: true
                    description: >-
                      Data e hora do cancelamento (ISO 8601); nula se não
                      cancelado.
                  expiresAt:
                    type: string
                    format: date-time
                    description: Data e hora de expiração (ISO 8601).
                  url:
                    type: string
                    description: >-
                      URL pública do checkout para o comprador finalizar o
                      pagamento.
              example:
                id: cs_02f232c4dcf8eec4c29e0f3748476d1339b63c0e7ffab1dc
                linkId: null
                status: created
                mode: payment
                currency: BRL
                locale: pt-BR
                config:
                  paymentMethods:
                    card:
                      enabled: true
                      installments:
                        maxInstallments: 12
                    pix:
                      enabled: true
                      expiresIn: 3600
                    boleto:
                      enabled: false
                  description: Consultoria avulsa
                customer:
                  name: Maria Souza
                  email: maria.souza@example.com
                  document: '12345678909'
                  documentType: cpf
                customFieldValues: null
                paymentMethodSelected: null
                subtotal: 50000
                discountTotal: 0
                amount: 50000
                discounts: []
                paymentAttempts: 0
                transactionId: null
                subscriptionId: null
                metadata: null
                createdAt: '2025-06-29T13:45:30.000Z'
                updatedAt: '2025-06-29T13:45:30.000Z'
                openedAt: null
                paidAt: null
                canceledAt: null
                expiresAt: '2025-06-30T13:45:30.000Z'
                url: >-
                  https://checkout.z2pay.com.br/c/s/cs_02f232c4dcf8eec4c29e0f3748476d1339b63c0e7ffab1dc
        '400':
          description: >-
            Requisição inválida — algum parâmetro ou campo do corpo não passou
            na validação
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Identificador estável do erro. É por ele que você deve
                          ramificar, não pela mensagem.
                      message:
                        type: string
                        description: >-
                          Descrição legível. Pode mudar sem aviso e não deve ser
                          usada em condicional.
                      issues:
                        type: array
                        description: >-
                          Um item por campo rejeitado. Nunca vem vazio: se há
                          400 de validação, há pelo menos um.
                        items:
                          type: object
                          properties:
                            path:
                              type: string
                              description: >-
                                Campo que falhou. Vem vazio quando o erro é do
                                corpo como um todo.
                            message:
                              type: string
                              description: O que há de errado com esse campo.
              example:
                error:
                  code: VALIDATION_ERROR
                  message: Validation failed
                  issues:
                    - path: status
                      message: >-
                        Status inválido. Valores aceitos: pending,
                        waiting_payment, paid, refused, canceled, refunded
                    - path: startDate
                      message: >-
                        Data deve ser ISO 8601 com timezone (ex.:
                        2026-06-24T00:00:00Z)
        '401':
          description: Chave de API ausente, malformada ou inválida
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Identificador estável do erro. É por ele que você deve
                          ramificar, não pela mensagem.
                      message:
                        type: string
                        description: >-
                          Descrição legível. Pode mudar sem aviso e não deve ser
                          usada em condicional.
              example:
                error:
                  code: UNAUTHORIZED
                  message: Invalid API key
        '403':
          description: >-
            A chave é válida, mas não tem permissão para esta operação — é o
            caso de usar uma publishable key (pk) onde a rota exige uma secret
            key (sk)
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Identificador estável do erro. É por ele que você deve
                          ramificar, não pela mensagem.
                      message:
                        type: string
                        description: >-
                          Descrição legível. Pode mudar sem aviso e não deve ser
                          usada em condicional.
              example:
                error:
                  code: FORBIDDEN
                  message: Forbidden — insufficient permissions
        '409':
          description: >-
            Já existe uma requisição em andamento com esta Idempotency-Key. A
            API aguarda a primeira concluir por até 5 segundos antes de
            responder assim
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: >-
                      Mensagem do conflito de idempotência. Aqui `error` é
                      texto, não objeto — ramifique pelo status HTTP.
              example:
                error: A request with this idempotency key is already being processed
        '422':
          description: >-
            Idempotency-Key já usada com um corpo diferente. Use uma chave nova
            para uma operação diferente
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: >-
                      Mensagem do conflito de idempotência. Aqui `error` é
                      texto, não objeto — ramifique pelo status HTTP.
              example:
                error: Idempotency key already used with a different request body
      security:
        - apiKey: []
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        API key unificada (z2_{live|test}_{sk|pk}_...) — secret (sk) para
        integração backend, publishable (pk) para uso no frontend público

````