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

# Create a Checkout Session

> Cria uma checkout session.

Uma **checkout session** é uma sessão temporária de compra. A Chargefy devolve `url` (página hospedada onde o cliente paga) e `client_secret` (lido pelo browser do comprador na hosted page). Ela coleta dados do comprador, apresenta os métodos disponíveis e confirma a escolha do comprador.

Diferente de um [payment link](/api-reference/payment-links/create) (URL pública reutilizável), a session nasce para uma compra específica e expira em 24h. Ela não é o livro-razão financeiro da cobrança; o resultado do pagamento é acompanhado por `payment_status`, `payment_intent` quando fizer parte do fluxo, invoices quando aplicável e webhooks.

<Tip>
  Veja [Ciclo de pagamento](/integrate/payment-lifecycle) para entender a
  relação entre checkout sessions, payment intents, invoices e payment methods.
</Tip>

## Autenticação

Header `Authorization: Bearer {{API_KEY}}`. Escopo necessário: `write`.

| Tipo de chave                            | O header `Organization` | Em nome de quem cria                                                           |
| ---------------------------------------- | ----------------------- | ------------------------------------------------------------------------------ |
| API key da organização                   | proibido                | a própria org dona da chave                                                    |
| API key da plataforma (`platform_admin`) | obrigatório             | a organização conectada indicada no header (deve estar ativa sob a plataforma) |

## Attributes

<ParamField body="allow_discount_codes" type="boolean" default="true">
  Permitir o comprador inserir códigos de cupom na hosted page.
</ParamField>

<ParamField body="branding_settings" type="object">
  Override **visual** desta sessão sobre a identidade da organização. `null` (ou omitido) herda 100% da organização. Cada campo presente sobrescreve só aquele campo; campo ausente herda. Veja [Branding](#branding).

  <Expandable title="Campos de branding_settings">
    <ParamField body="accent_color" type="string">Cor de destaque (botão/foco), hex `#RGB` ou `#RRGGBB`.</ParamField>
    <ParamField body="border_style" type="string">`pill`, `rounded` ou `sharp`.</ParamField>
    <ParamField body="brand_color" type="string">Cor de marca (painel/cabeçalho), hex `#RGB` ou `#RRGGBB`.</ParamField>
    <ParamField body="font_family" type="string">`system`, `inter`, `geist` ou `bitter`.</ParamField>
    <ParamField body="theme" type="string">`light` ou `dark`.</ParamField>
  </Expandable>
</ParamField>

<ParamField body="cancel_url" type="string">
  URL pra onde a Chargefy redireciona se o cliente abandonar a sessão (botão
  "Voltar" na hosted page).
</ParamField>

<ParamField body="customer_document" type="string">
  CPF ou CNPJ do comprador (pré-preenche).
</ParamField>

<ParamField body="customer_document_type" type="string">
  `cpf` ou `cnpj`. Envie junto de `customer_document`.
</ParamField>

<ParamField body="customer_email" type="string">
  Email do comprador (pré-preenche o formulário da hosted page).
</ParamField>

<ParamField body="customer_id" type="string">
  ID de um customer já existente da organização conectada. Se omitido, a
  Chargefy cria um novo customer no confirm com os dados da sessão/comprador;
  não há dedupe automático por email ou CPF/CNPJ no nível de `customer`.
</ParamField>

<ParamField body="customer_name" type="string">
  Nome do comprador (pré-preenche).
</ParamField>

<ParamField body="discount_id" type="string">
  ID de um desconto pré-aplicado da organização conectada alvo.
</ParamField>

<ParamField body="invoice_creation" type="boolean" default="false">
  Quando `true` e a session é `mode=payment`, o pagamento bem-sucedido
  materializa uma invoice canônica. Padrão `false` — pagamentos one-shot não
  geram invoice. Sessions `mode=subscription` sempre materializam invoice via a
  assinatura, independente desse campo (passar `false` aqui em sub-mode é erro
  400\).
</ParamField>

<ParamField body="line_items" type="array" required>
  Array não-vazio de itens. Cada item descreve um produto/preço cobrado nessa
  sessão. Aceita três formas — veja [Três
  variantes](#line-items-tres-variantes).
</ParamField>

<ParamField body="metadata" type="object">
  Objeto livre `string → string`, opcional e definido pelo parceiro. É ecoado em
  todos os webhooks `checkout.session.*` correspondentes. Limite: 50 chaves,
  chave com 40 caracteres e valor com 500 caracteres.
</ParamField>

<ParamField body="payment_method_collection" type="string" default="always">
  Apenas para sessões `subscription`. Um de `always` ou `if_required`. `always`
  coleta cartão mesmo quando a assinatura não tem cobrança no momento da
  confirmação, como trial gratuito ou preço recorrente gratuito. `if_required`
  permite concluir sem coletar cartão quando não há cobrança no momento da
  confirmação.
</ParamField>

<ParamField body="payment_method_options" type="object">
  Opções por método de pagamento. Quando omitido, aplicam-se os padrões da
  organização.

  <Expandable title="Campos de payment_method_options">
    <ParamField body="credit_card" type="object">
      Opções do cartão de crédito.

      <Expandable title="Campos de credit_card">
        <ParamField body="installments" type="object">
          Configuração do parcelamento.

          <Expandable title="Campos de installments">
            <ParamField body="has_interest" type="boolean">
              `true` quando o comprador paga o acréscimo do parcelamento;
              `false` quando o lojista absorve o acréscimo. Quando omitido, usa o
              padrão da organização.
            </ParamField>

            <ParamField body="max_count" type="integer">
              Número máximo de parcelas oferecidas (1–12). Quando omitido, usa o
              padrão da organização.
            </ParamField>
          </Expandable>
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="payment_method_types" type="array">
  Subconjunto dos meios de pagamento habilitados na organização conectada. Use
  `credit_card`, `pix` e/ou `boleto`. Quando omitido, a sessão usa os meios
  configurados na organização.
</ParamField>

<ParamField body="require_billing_address" type="boolean">
  Exigir endereço de cobrança no formulário. Quando omitido, herda a política de
  checkout da organização. Boleto sempre exige endereço, independente deste
  valor.
</ParamField>

<ParamField body="require_document" type="boolean">
  Exigir o documento (CPF/CNPJ) do comprador no formulário. Quando omitido,
  herda a política de checkout da organização (padrão `true`). Boleto sempre
  exige documento, independente deste valor.
</ParamField>

<ParamField body="require_phone" type="boolean">
  Exigir o telefone do comprador no formulário. Quando omitido, herda a política
  de checkout da organização (padrão `false`).
</ParamField>

<ParamField body="submit_type" type="string" default="auto">
  Tipo semântico do botão de finalização. Um de `auto`, `pay`, `subscribe`,
  `book`, `donate`. Controla a **cópia** do botão, que a hosted page renderiza
  no idioma do comprador. `auto` (padrão) escolhe a cópia pelo tipo da sessão
  (one-shot → "Pagar", recorrente → "Assinar"). Use um valor explícito quando a
  transação for reserva (`book`) ou doação (`donate`).
</ParamField>

<ParamField body="subscription_data" type="object">
  Input transitório usado apenas quando a sessão é `mode=subscription`. A
  session guarda esse snapshot para audit/debug, mas o estado durável de trial
  fica na `subscription` criada no confirm.

  <Expandable title="Campos de subscription_data">
    <ParamField body="metadata" type="object">
      Metadata inicial da assinatura.
    </ParamField>

    <ParamField body="trial_end" type="string">
      Timestamp ISO 8601 exato para o fim do trial.
    </ParamField>

    <ParamField body="trial_period_days" type="integer">
      Dias de trial. Use apenas um entre `trial_period_days` e `trial_end`.
    </ParamField>

    <ParamField body="trial_settings" type="object">
      Política de fim de trial. `end_behavior.missing_payment_method` aceita
      `create_invoice`, `pause` ou `cancel`.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="success_url" type="string">
  URL pra onde a Chargefy redireciona o cliente após pagamento confirmado.
</ParamField>

<ParamField body="template" type="string">
  Template visual da página hospedada. Um de `minimal`, `booking` ou
  `subscription`. Quando omitido, a sessão usa o template padrão da organização.
</ParamField>

<Tip>
  **Quando criar campo na raiz vs. usar `metadata`?** Tudo que é estrutural (com
  tipagem, validação, semântica concreta na Chargefy) é na raiz. `metadata` é
  livre, opcional, parceiro decide. Campos obrigatórios nunca moram em
  `metadata`.
</Tip>

## line\_items — três variantes

Cada item de `line_items` aceita exatamente uma destas três formas. Use a mais idiomática pro seu caso.

### (a) Preço do catálogo

Caminho mais curto. Resolve produto, valor e (se for o caso) recorrência automaticamente a partir do `price_id`.

<RequestExample>
  ```bash cURL theme={}
  curl -X POST "https://api.chargefy.io/v1/checkout-sessions" \
    -H "Authorization: Bearer {{API_KEY}}" \
    -H "Content-Type: application/json" \
    -d '{
      "line_items": [
        {
          "price_id": "price_123"
        }
      ]
    }'
  ```
</RequestExample>

### (b) Produto do catálogo + preço ad-hoc

Reusa nome/descrição do produto cadastrado, mas com valor único pra essa sessão. Não cria preço novo no catálogo.

<RequestExample>
  ```bash cURL theme={}
  curl -X POST "https://api.chargefy.io/v1/checkout-sessions" \
    -H "Authorization: Bearer {{API_KEY}}" \
    -H "Content-Type: application/json" \
    -d '{
      "line_items": [
        {
          "price_data": {
            "currency": "brl",
            "product_id": "prod_123",
            "unit_amount": 12990
          }
        }
      ]
    }'
  ```
</RequestExample>

### (c) Produto e preço ad-hoc

Nada vem do catálogo. Útil pra integrações headless que não cadastram produto.

<RequestExample>
  ```bash cURL theme={}
  curl -X POST "https://api.chargefy.io/v1/checkout-sessions" \
    -H "Authorization: Bearer {{API_KEY}}" \
    -H "Content-Type: application/json" \
    -d '{
      "line_items": [
        {
          "price_data": {
            "currency": "brl",
            "product_data": {
              "name": "Consultoria avulsa"
            },
            "unit_amount": 4990
          }
        }
      ]
    }'
  ```
</RequestExample>

### Pagamento one-shot com invoice (`invoice_creation`)

Passe `invoice_creation: true` quando precisar de uma invoice canônica
materializada no sucesso da cobrança — útil pra reconciliação contábil ou
emissão fiscal a partir de um documento próprio. Sem o flag, `mode=payment`
não gera invoice; `mode=subscription` sempre gera independentemente.

<RequestExample>
  ```bash cURL theme={}
  curl -X POST "https://api.chargefy.io/v1/checkout-sessions" \
    -H "Authorization: Bearer {{API_KEY}}" \
    -H "Organization: {{ORGANIZATION_ID}}" \
    -H "Content-Type: application/json" \
    -d '{
      "invoice_creation": true,
      "line_items": [
        {
          "price_id": "price_111",
          "quantity": 1
        }
      ],
      "success_url": "https://meusite.com/sucesso"
    }'
  ```
</RequestExample>

### Recorrência

Em (a), basta o `price_id` apontar pra um preço com `recurring` preenchido — a sessão nasce em `mode: subscription` sem campos extras. Em (b) e (c), adicione `price_data.recurring`:

```json theme={}
{
  "price_data": {
    "currency": "brl",
    "product_id": "prod_222",
    "recurring": {
      "interval": "month",
      "interval_count": 1
    },
    "unit_amount": 12990
  }
}
```

Para trial em checkout de assinatura, use `subscription_data`. A session guarda
esse input como snapshot, mas a assinatura criada no confirm passa a ser a fonte
de verdade (`trial_start`, `trial_end`, `trial_settings`).

Por padrão, a hosted page coleta cartão quando a assinatura não tem cobrança no
momento da confirmação (`payment_method_collection: "always"`), preparando a
cobrança automática de ciclos pagos futuros. Para permitir concluir sem cartão
quando nada é devido agora, envie `payment_method_collection: "if_required"`.

```json theme={}
{
  "line_items": [
    {
      "price_id": "price_111",
      "quantity": 1
    }
  ],
  "payment_method_collection": "always",
  "subscription_data": {
    "trial_period_days": 14,
    "trial_settings": {
      "end_behavior": {
        "missing_payment_method": "pause"
      }
    }
  },
  "success_url": "https://meusite.com/sucesso"
}
```

### Restrições do array

* Todos os itens compartilham a mesma `currency`.
* Ou **todos** os itens são recorrentes, ou **nenhum** é. Misturar one-shot com recorrente retorna 400.
* Cada item tem exatamente um entre `price_id` ou `price_data`.
* Quando `price_data` é usado, exatamente um entre `product_id` e `product_data` deve acompanhá-lo.

## Branding

A identidade visual da página hospedada vem da **organização** (cor, fonte, tema, formato de borda — configurada uma vez em [organizations](/api-reference/organizations/update)). A checkout session pode **sobrescrever** campos visuais pontualmente via `branding_settings`.

O contrato é por campo: cada campo presente em `branding_settings` vence o default da organização; cada campo ausente herda. `branding_settings: null` (ou omitido) herda tudo.

<Info>
  A resposta da API devolve o `branding_settings` **cru** — só o que você
  sobrescreveu nesta sessão, sem mesclar com a organização. A mescla final
  (override da sessão + defaults da organização) é resolvida pela página
  hospedada no momento de renderizar. Assim o que você envia é o que você lê de
  volta.
</Info>

`submit_type` **não** é branding — é a cópia semântica do botão e mora na raiz da sessão.

## Templates

`template` controla a estrutura do painel esquerdo da página hospedada. O painel
de pagamento permanece o mesmo em todos os templates.

<CardGroup cols={3}>
  <Card title="minimal" icon="square" href="/features/checkout-templates">
    <img src="https://mintcdn.com/scaleup-28315a31/oU8B8kPbmC19xOC_/assets/checkout-template-minimal.jpg?fit=max&auto=format&n=oU8B8kPbmC19xOC_&q=85&s=eb14fae53618ea43855b1ca0c1e4c8cf" alt="Miniatura do template minimal com produto, resumo e formulário de pagamento" width="1280" height="800" data-path="assets/checkout-template-minimal.jpg" />
  </Card>

  <Card title="booking" icon="calendar-days" href="/features/checkout-templates">
    <img src="https://mintcdn.com/scaleup-28315a31/JkjvjdzrXEcQicBB/assets/checkout-template-booking.jpg?fit=max&auto=format&n=JkjvjdzrXEcQicBB&q=85&s=563b122cd34ff72a8e69cba6f65c1c7f" alt="Miniatura do template booking com estadia, noites e adicionais" width="1280" height="800" data-path="assets/checkout-template-booking.jpg" />
  </Card>

  <Card title="subscription" icon="arrows-rotate" href="/features/checkout-templates">
    <img src="https://mintcdn.com/scaleup-28315a31/kSlvsTruhKR3KP8Z/assets/checkout-template-subscription.jpg?fit=max&auto=format&n=kSlvsTruhKR3KP8Z&q=85&s=0f1ba4b30ca5e6f529ea9cc5caeb88af" alt="Miniatura do template subscription com trial, ciclo de cobrança e valor por mês" width="1280" height="800" data-path="assets/checkout-template-subscription.jpg" />
  </Card>
</CardGroup>

| Valor          | Uso                                                            |
| -------------- | -------------------------------------------------------------- |
| `minimal`      | Produto/preço e resumo padrão.                                 |
| `booking`      | Reservas de hospedagem com estadia, noites e adicionais/taxas. |
| `subscription` | Assinaturas com trial, ciclo de cobrança e valor por mês.      |

No `booking`, envie a acomodação como primeiro `line_items[]`: `price_data.product_id`
aponta para o produto da acomodação, `unit_amount` é a diária dinâmica e
`quantity` é o número de noites. Itens seguintes representam adicionais ou
taxas cobradas.

No `subscription`, use `line_items[]` com preços recorrentes (`recurring`) e,
quando houver período de teste, envie `subscription_data.trial_period_days` (ou
`subscription_data.trial_end`). A página destaca o trial, o ciclo de cobrança e
o valor por mês equivalente, e mostra `R$ 0,00` como total devido hoje durante o
trial.

<RequestExample>
  ```bash cURL theme={}
  curl -X POST "https://api.chargefy.io/v1/checkout-sessions" \
    -H "Authorization: Bearer {{API_KEY}}" \
    -H "Organization: {{ORGANIZATION_ID}}" \
    -H "Content-Type: application/json" \
    -d '{
      "branding_settings": {
        "accent_color": "#A0D2DB",
        "border_style": "pill"
      },
      "line_items": [
        {
          "price_data": {
            "currency": "brl",
            "product_id": "prod_suite_123",
            "unit_amount": 45000
          },
          "quantity": 3
        },
        {
          "price_data": {
            "currency": "brl",
            "product_data": {
              "name": "Taxa de limpeza"
            },
            "unit_amount": 12000
          },
          "quantity": 1
        }
      ],
      "submit_type": "book",
      "success_url": "https://meusite.com/sucesso",
      "template": "booking"
    }'
  ```
</RequestExample>

## Resposta

<ResponseField name="id" type="string">
  ID da checkout session.
</ResponseField>

<ResponseField name="object" type="string">
  Sempre `checkout.session`.
</ResponseField>

<ResponseField name="allow_discount_codes" type="boolean">
  Eco do body (default `true`).
</ResponseField>

<ResponseField name="amount_discount" type="integer">
  Desconto aplicado, em centavos.
</ResponseField>

<ResponseField name="amount_subtotal" type="integer">
  Soma dos `line_items`, em centavos, antes de descontos e impostos.
</ResponseField>

<ResponseField name="amount_tax" type="integer">
  Impostos aplicados, em centavos.
</ResponseField>

<ResponseField name="amount_total" type="integer">
  Total cobrado, em centavos. = subtotal − discount + tax.
</ResponseField>

<ResponseField name="branding_settings" type="object | null">
  Override visual **cru** desta sessão — só os campos que você sobrescreveu, sem
  mescla com a organização. `null` quando não houve override. Não é o branding
  resolvido (esse é aplicado pela página hospedada).
</ResponseField>

<ResponseField name="cancel_url" type="string | null">
  Eco do que veio no body.
</ResponseField>

<ResponseField name="client_secret" type="string">
  String opaca de 64 caracteres hex, sem prefixo. Usada pela hosted page pra
  abrir a sessão sem precisar do token de API. Não é segredo de servidor — é
  runtime do browser.
</ResponseField>

<ResponseField name="created_at" type="string">
  ISO-8601.
</ResponseField>

<ResponseField name="currency" type="string">
  Moeda em ISO 4217 minúsculo (ex: `brl`).
</ResponseField>

<ResponseField name="customer" type="string | null">
  Vem `null` no create — a Chargefy resolve customer só no confirm (lazy).
  Aparece preenchido nos webhooks de `checkout.session.completed` em diante.
</ResponseField>

<ResponseField name="customer_document" type="string | null">
  Mesmo padrão de `customer_email`.
</ResponseField>

<ResponseField name="customer_document_type" type="string | null">
  `cpf`, `cnpj` ou `null`.
</ResponseField>

<ResponseField name="customer_email" type="string | null">
  Pré-preenchido se enviado no body; senão `null`. Atualizado quando o comprador
  preenche o formulário.
</ResponseField>

<ResponseField name="customer_name" type="string | null">
  Mesmo padrão de `customer_email`.
</ResponseField>

<ResponseField name="discount" type="string | null">
  Eco do body.
</ResponseField>

<ResponseField name="expires_at" type="string">
  ISO-8601. 24h depois do `created_at`.
</ResponseField>

<ResponseField name="invoice_creation" type="boolean">
  Eco do body (default `false` em `mode=payment`).
</ResponseField>

<ResponseField name="line_items" type="array">
  Snapshot dos itens da sessão (resolvido com produto/preço/recorrência conforme
  a variante usada).
</ResponseField>

<ResponseField name="livemode" type="boolean">
  Indica se a sessão foi criada em modo live.
</ResponseField>

<ResponseField name="metadata" type="object">
  Eco do body (default `{}`).
</ResponseField>

<ResponseField name="mode" type="string">
  `payment` (one-shot) ou `subscription` (recorrente).
</ResponseField>

<ResponseField name="payment_data" type="object | null">
  `null` no create. Aparece preenchido depois do `confirm`.
</ResponseField>

<ResponseField name="payment_method_collection" type="string">
  Em sessões `subscription`, indica se a hosted page coleta cartão sempre
  (`always`) ou somente quando houver cobrança no momento da confirmação
  (`if_required`). Em sessões `payment`, o valor é `always`.
</ResponseField>

<ResponseField name="payment_method_options" type="object">
  Opções por método de pagamento oferecidas na hosted page.

  <Expandable title="Campos de payment_method_options">
    <ResponseField name="credit_card" type="object">
      Opções do cartão de crédito.

      <Expandable title="Campos de credit_card">
        <ResponseField name="installments" type="object">
          Configuração do parcelamento.

          <Expandable title="Campos de installments">
            <ResponseField name="has_interest" type="boolean">
              `true` quando o comprador paga o acréscimo do parcelamento;
              `false` quando o lojista absorve o acréscimo.
            </ResponseField>

            <ResponseField name="max_count" type="integer">
              Número máximo de parcelas oferecidas (1–12).
            </ResponseField>
          </Expandable>
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="payment_method_types" type="string[]">
  Métodos disponíveis pro comprador na hosted page (ex: `["credit_card", "pix",
      "boleto"]`). É o subconjunto salvo na sessão: ou o valor enviado em
  `payment_method_types`, ou os meios configurados na organização quando o campo
  foi omitido. Esse conjunto é um snapshot imutável — a hosted page, a consulta,
  a confirmação e os webhooks da sessão sempre devolvem exatamente esses
  métodos, independente de mudanças posteriores na política da organização.
</ResponseField>

<ResponseField name="payment_status" type="string">
  `unpaid`, `paid`, `no_payment_required` (total = 0).
</ResponseField>

<ResponseField name="require_billing_address" type="boolean">
  Política resolvida (body ou default da organização). Boleto sempre exige.
</ResponseField>

<ResponseField name="require_document" type="boolean">
  Política resolvida (body ou default da organização, padrão `true`). Boleto
  sempre exige documento.
</ResponseField>

<ResponseField name="require_phone" type="boolean">
  Política resolvida (body ou default da organização, padrão `false`).
</ResponseField>

<ResponseField name="status" type="string">
  `open` (criada, aguardando pagamento), `complete` (cliente confirmou),
  `expired` (24h sem confirm — terminal).
</ResponseField>

<ResponseField name="submit_type" type="string">
  Eco do body (default `auto`). Um de `auto`, `pay`, `subscribe`, `book`,
  `donate`.
</ResponseField>

<ResponseField name="subscription" type="string | null">
  Subscription criada por uma sessão `mode=subscription`. Vem `null` no create.
</ResponseField>

<ResponseField name="success_url" type="string | null">
  Eco do que veio no body.
</ResponseField>

<ResponseField name="template" type="string | null">
  Template explícito da sessão. `null` significa que a página hospedada usa o
  padrão da organização.
</ResponseField>

<ResponseField name="url" type="string">
  URL hospedada da Chargefy. Redirecione o comprador pra essa URL.
</ResponseField>

<ResponseExample>
  ```json 200 theme={}
  {
    "id": "id_111",
    "object": "checkout.session",
    "allow_discount_codes": true,
    "amount_discount": 0,
    "amount_subtotal": 147000,
    "amount_tax": 0,
    "amount_total": 147000,
    "branding_settings": {
      "accent_color": "#A0D2DB",
      "border_style": "pill",
      "brand_color": null,
      "font_family": null,
      "theme": null
    },
    "cancel_url": null,
    "client_secret": "9f4c2a1b8e3d7f06a5c4b2e1d8f3a6b09c5e2a1f4b7d8c3e6a9f1d2c4b5e8a0f",
    "created_at": "2026-05-03T18:31:00Z",
    "currency": "brl",
    "customer": null,
    "customer_document": null,
    "customer_document_type": null,
    "customer_email": null,
    "customer_name": null,
    "discount": null,
    "expires_at": "2026-05-04T18:31:00Z",
    "invoice_creation": false,
    "line_items": [
      {
        "id": "id_333",
        "amount_discount": 0,
        "amount_subtotal": 135000,
        "amount_tax": 0,
        "amount_total": 135000,
        "currency": "brl",
        "description": "Suíte Vista Mar",
        "metadata": {},
        "position": 0,
        "price": null,
        "price_data": {
          "currency": "brl",
          "product_id": "prod_suite_123",
          "unit_amount": 45000
        },
        "product": "prod_suite_123",
        "quantity": 3,
        "recurring_interval": null,
        "recurring_interval_count": null,
        "unit_amount": 45000
      },
      {
        "id": "id_444",
        "amount_discount": 0,
        "amount_subtotal": 12000,
        "amount_tax": 0,
        "amount_total": 12000,
        "currency": "brl",
        "description": "Taxa de limpeza",
        "metadata": {},
        "position": 1,
        "price": null,
        "price_data": {
          "currency": "brl",
          "product_data": {
            "name": "Taxa de limpeza"
          },
          "unit_amount": 12000
        },
        "product": null,
        "quantity": 1,
        "recurring_interval": null,
        "recurring_interval_count": null,
        "unit_amount": 12000
      }
    ],
    "livemode": true,
    "metadata": {
      "order_id": "ord_123"
    },
    "mode": "payment",
    "payment_data": null,
    "payment_method_collection": "always",
    "payment_method_options": {
      "credit_card": {
        "installments": {
          "has_interest": true,
          "max_count": 12
        }
      }
    },
    "payment_method_types": [
      "credit_card",
      "pix",
      "boleto"
    ],
    "payment_status": "unpaid",
    "require_billing_address": false,
    "require_document": true,
    "require_phone": false,
    "status": "open",
    "submit_type": "book",
    "subscription": null,
    "success_url": "https://meusite.com/sucesso",
    "template": "booking",
    "url": "https://pay.chargefy.io/session/9f4c2a1b8e3d7f06a5c4b2e1d8f3a6b09c5e2a1f4b7d8c3e6a9f1d2c4b5e8a0f"
  }
  ```

  ```json 400 theme={}
  {
    "error": {
      "code": "invalid_request",
      "message": "line_items is required and must be a non-empty array.",
      "param": "line_items",
      "type": "invalid_request_error"
    }
  }
  ```

  ```json 401 theme={}
  {
    "error": {
      "code": "authentication_failed",
      "message": "Invalid API key provided.",
      "type": "authentication_error"
    }
  }
  ```

  ```json 403 theme={}
  {
    "error": {
      "code": "permission_denied",
      "message": "Organization header must point to an active connected organization.",
      "type": "authentication_error"
    }
  }
  ```
</ResponseExample>

## Próximo passo

Redirecione o comprador pra `resposta.url`. A Chargefy renderiza a página de pagamento, confirma o método escolhido e devolve o cliente em `success_url` ao final.

```ts theme={}
window.location.assign(response.url);
```

O frontend da hosted page chama [`POST /v1/checkout-sessions/public/:client_secret/confirm`](/api-reference/checkout-sessions/confirm) sozinho. Seu servidor não precisa criar nem confirmar uma movimentação interna de processamento para uma checkout session.

## Erros

| HTTP | Razão                                                                                                                                 |
| ---- | ------------------------------------------------------------------------------------------------------------------------------------- |
| 400  | `line_items` ausente, vazio, ou item sem `price_id` nem `price_data`                                                                  |
| 400  | Item com `price_id` e `price_data` juntos (envie exatamente um)                                                                       |
| 400  | `price_data` sem `product_id` nem `product_data` — ou com ambos                                                                       |
| 400  | Mistura de itens recorrentes e únicos no mesmo `line_items`                                                                           |
| 400  | Currency divergente entre os itens                                                                                                    |
| 400  | `price_id` ou `product_id` não existe na organização conectada alvo                                                                   |
| 400  | `customer_id` (quando passado) não pertence à organização conectada alvo                                                              |
| 401  | `Authorization` ausente, mal formado ou inválido                                                                                      |
| 403  | Token de plataforma sem header `Organization`, ou `Organization` apontando para uma organização conectada não ativa da sua plataforma |

<Info>
  **Organização conectada sem cadastro financeiro concluído** não bloqueia a
  criação — a sessão nasce com `payment_method_types: []`. Trate o array vazio
  antes de redirecionar o comprador (ou aborte criação no seu lado se preferir).
</Info>
