> ## 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.

# Links

> Crie templates de cobrança reutilizáveis (chk_): uma URL para divulgar N vezes, cada acesso vira uma Session.

Um **Checkout Link** (`chk_`) é um **template de cobrança reutilizável**. Você define uma vez os
itens, o preço, os métodos e o branding, e divulga a URL quantas vezes quiser — cada acesso de
comprador materializa uma **Session** independente. É o formato para link na bio, página de captura
ou qualquer divulgação em massa.

Para cobrar **uma pessoa uma vez**, sem template, o caminho é a
[venda rápida](/pt-BR/checkout/charges).

<Info>
  Todas as rotas exigem o header `x-api-key`. Veja [Autenticação](/pt-BR/autenticacao). Os exemplos
  usam a base URL de sandbox `https://api.sandbox.z2pay.com/v1`, e a página hospedada de sandbox é
  `https://pay.sandbox.z2pay.com`.
</Info>

***

## Endpoints

Cada endpoint tem sua própria página, com os campos aceitos, exemplos e o playground para testar.

| Método   | Rota                      | Descrição                                                       |
| -------- | ------------------------- | --------------------------------------------------------------- |
| `POST`   | `/checkout/links`         | [Cria um template de cobrança](/pt-BR/checkout/links/create)    |
| `GET`    | `/checkout/links`         | [Lista os templates](/pt-BR/checkout/links/list)                |
| `GET`    | `/checkout/links/{id}`    | [Busca um template pelo ID](/pt-BR/checkout/links/get)          |
| `PATCH`  | `/checkout/links/{id}`    | [Atualiza um template](/pt-BR/checkout/links/update)            |
| `DELETE` | `/checkout/links/{id}`    | [Arquiva um template](/pt-BR/checkout/links/delete)             |
| `POST`   | `/checkout/sessions`      | [Cria uma Session avulsa](/pt-BR/checkout/links/session-create) |
| `GET`    | `/checkout/sessions`      | [Lista as Sessions](/pt-BR/checkout/links/session-list)         |
| `GET`    | `/checkout/sessions/{id}` | [Busca uma Session pelo ID](/pt-BR/checkout/links/session-get)  |

***

## Do Link à Session

O Link é o molde; a **Session** (`cs_`) é a compra. Quando um comprador abre a URL — ou quando você
cria uma [venda rápida](/pt-BR/checkout/charges) — a Z2Pay materializa uma Session com o valor
congelado e um estado que avança conforme ele interage.

**O snapshot é imutável.** Itens, preço, splits, branding e métodos são copiados para a Session no
momento em que ela nasce. Editar o Link depois não alcança Sessions já criadas: o comprador paga
exatamente o que viu quando abriu a página.

Em Session que veio de um Link, `linkId` aponta para o template de origem; em Session de venda
rápida, `linkId` é `null`. Nos dois casos, `transactionId` liga a Session ao pagamento — e é
preenchido quando ela entra em `paying`.

<Warning>
  **`status: "active"` não quer dizer que o Link vende.** São dois campos independentes: `status`
  (`active`/`archived`) é decisão **sua**; `sellable` é decisão **nossa** — vira `false` quando
  alguém que precisa receber o dinheiro deixa de poder, seja um recebedor do `splits` ou o dono da
  conta, e volta a `true` sozinho quando o cadastro é regularizado.

  A combinação que engana é `active` + `sellable: false`: você não arquivou nada, e quem abrir a URL
  vê "checkout temporariamente indisponível". Nenhuma Session nova nasce e o pagamento é recusado. Um
  painel que mostra "no ar" olhando só o `status` vai mentir no dia em que um parceiro do split for
  reprovado no cadastro — **confira os dois**.

  O motivo do bloqueio não é devolvido: ele fala do estado cadastral de terceiros. O que a API
  responde é o fato — vende ou não vende.
</Warning>

***

## Estados da Session

O caminho feliz é `created → opened → filling → paying → paid`.

| Estado           | O que significa               | Quando acontece                                                                                                                    |
| ---------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `created`        | Session existe, ninguém abriu | Materializada pelo Link ou pela venda rápida                                                                                       |
| `opened`         | Comprador abriu a página      | Primeiro acesso à URL                                                                                                              |
| `filling`        | Comprador preenchendo         | A página envia os dados parciais enquanto ele digita                                                                               |
| `paying`         | Cobrança em processamento     | Comprador clicou em "Pagar"                                                                                                        |
| `partially_paid` | Parte do total confirmou      | Só no pagamento combinado: o Pix pagou, o cartão ainda não                                                                         |
| `paid`           | Pagamento confirmado          | Terminal. Dispara `transaction.paid`                                                                                               |
| `failed`         | Pagamento recusado            | A Session volta a `opened` sozinha, para permitir nova tentativa                                                                   |
| `abandoned`      | Comprador parou no meio       | Inatividade dentro do prazo. **Recuperável**: se ele voltar e confirmar, vai direto a `paying`                                     |
| `expired`        | Prazo esgotado                | `expiresAt` atingido sem confirmação. Terminal                                                                                     |
| `canceled`       | Cancelamento manual           | Terminal. Em venda rápida, por [`POST /checkout/charges/{id}/cancel`](/pt-BR/checkout/charges/cancel); no painel, qualquer Session |

<Note>
  **Expirar não alcança quem está pagando.** Sessions em `paying` ou `partially_paid` nunca são
  expiradas pelo processo automático — quem está no meio de um pagamento não perde a compra por
  tempo. Os demais estados não-terminais expiram ao atingir `expiresAt`.
</Note>

<Note>
  **`partially_paid` e `paying → opened` são exclusivos do combinado.** Em pagamento por um método
  só, a Session vai direto de `paying` para `paid` ou `failed`. A volta para `opened` acontece
  quando os cartões falham mas o Pix ou o boleto seguem pendentes, devolvendo o comprador à página
  para tentar outra composição.
</Note>

<Note>
  **Duas requisições não confirmam a mesma Session.** Toda transição é protegida por controle de
  concorrência: se duas chegarem juntas, só uma vence — a outra recebe
  `session_already_processing` ou `invalid_status_transition`. O contador que faz esse controle é
  interno e não sai na resposta.
</Note>

***

## Assinaturas via Checkout

Um Link com `mode: "subscription"` vende uma **assinatura recorrente**: o comprador paga a primeira
cobrança na página hospedada e a Z2Pay ativa a assinatura sozinha. O modelo de planos, ciclos e
faturas está em [Assinaturas](/pt-BR/subscriptions/visao-geral).

Cinco regras que nenhum schema expressa:

* **`mode` e o objeto `subscription` andam juntos** — enviar um sem o outro é recusado.
* **Pagamento combinado não vale aqui** — `paymentMethods.combined.enabled` é recusado em Link de
  assinatura. Pelo menos um método precisa estar habilitado.
* **Só por Link** — a [venda rápida](/pt-BR/checkout/charges) recusa `mode: "subscription"`.
  Recorrência não nasce de Session avulsa.
* **Adesão e trial se excluem** — item com `chargeType: "activation"` e `subscription.trialDays > 0`
  no mesmo Link é recusado. São opostos: a adesão cobra a mais no começo, o trial cobra a menos.
* **Com trial, só cartão** — e para validá-lo o checkout faz uma cobrança de **R\$ 1,23**
  (`123` centavos) **estornada automaticamente**. A assinatura nasce em trial, sem cobrança real até
  o fim do período.

**A ativação é assíncrona.** Depois do pagamento, a Z2Pay cria a assinatura aproveitando a cobrança
já feita — a primeira fatura nasce paga, sem cobrar o comprador de novo — e a Session ganha
`subscriptionId` (`sub_`).

<Note>
  **Espere o `subscriptionId` antes de concluir que deu errado.** A ativação leva alguns segundos, e
  se falhar o worker retenta sozinho a cada 60 segundos, até cinco vezes — cinco minutos no pior
  caso. Consulte a Session de novo em vez de tratar o campo nulo como erro.

  Passado esse prazo com `subscriptionId` ainda nulo, o motivo da falha fica em
  `session.metadata.subscription_activation_error`. A recuperação é manual: **fale com o suporte** com
  o `cs_` em mãos.
</Note>

**A assinatura criada carrega a origem no `metadata`.** Na ativação, a Z2Pay grava três chaves
reservadas no `metadata` da assinatura — e elas saem em **todos** os eventos `subscription.*`,
inclusive nos que não têm ação do comprador, como `subscription.past_due` e
`subscription.canceled`:

| Chave                             | Conteúdo                                                           |
| --------------------------------- | ------------------------------------------------------------------ |
| `metadata.checkoutLinkId`         | O `chk_` do Link que vendeu a assinatura                           |
| `metadata.checkoutSessionId`      | O `cs_` da Session daquela compra                                  |
| `metadata.bootstrapTransactionId` | O `txn_` da primeira cobrança (no trial, o da validação de cartão) |

É o que permite reagir aos eventos sem guardar estado do seu lado: libere o acesso no
`transaction.paid` — que traz `additionalInfo.checkoutLinkId` — e suspenda ou revogue no
`subscription.past_due` / `subscription.canceled` usando o mesmo `chk_`, lido direto do evento.
Como toda chave reservada, se o seu `metadata` definir uma homônima, o valor da Z2Pay prevalece.

<Note>
  **O primeiro `transaction.paid` sai sem `subscriptionId`** — ele dispara antes de a assinatura
  existir. Depois da ativação, a transação daquela compra ganha `additionalInfo.subscriptionId`
  (visível ao consultá-la e nos eventos posteriores dela, como estorno e chargeback). Para ligar
  venda e assinatura já no primeiro evento, ouça também `subscription.created` e correlacione pelo
  `metadata.checkoutSessionId`, que é igual ao `referenceCode` da transação. Das cobranças
  recorrentes em diante, os eventos `transaction.*` já saem com `additionalInfo.subscriptionId`.
</Note>

***

## Reconciliação

**Você não define um código de referência no Checkout.** Não existe campo `referenceCode` na
criação de Link, venda rápida ou Session — o que você grava é `metadata`. Quem preenche o
`referenceCode` da transação é a Z2Pay, com o `id` da Session (`cs_...`).

Para reconciliar por webhook, **não espere eventos `checkout.session.*`** — eles são internos e não
existem no [catálogo](/pt-BR/webhooks/eventos). Use os eventos de transação: `transaction.paid` e
`transaction.refused`. A correlação funciona pelos dois lados:

* `data.id` (o `txn_`) é igual ao `transactionId` da Session; **ou**
* `data.referenceCode` é igual ao `id` da Session.

**Para saber de qual Link veio a venda, use `data.additionalInfo.checkoutLinkId`.** O `cs_` muda a
cada comprador; o `chk_` é o mesmo em todas as vendas do Link — é a chave para mapear "este checkout
entrega tal produto" do seu lado. A chave é reservada: se o seu `metadata` definir uma
`checkoutLinkId`, o valor da Z2Pay prevalece. Vendas sem Link (venda rápida, Session avulsa) não a
trazem. O estorno da venda também a carrega: os eventos `refund.*` e as respostas de
[Reembolsos](/pt-BR/refunds) saem com `additionalInfo.checkoutLinkId` copiado da transação, então o
estorno chega ao Link sem consulta extra.

O `metadata` que você gravou **na Session ou na venda rápida** volta em `data.additionalInfo`, com
as suas chaves no primeiro nível — o `metadata` do Link fica no Link e não é copiado para a
transação. Os campos customizados preenchidos pelo comprador entram ali sob `checkoutCustomFields`,
como um array de `{ key, label, type, value }` — só os que foram respondidos.

***

## Veja também

<CardGroup cols={2}>
  <Card title="Visão geral do Checkout" icon="layout-template" href="/pt-BR/checkout/visao-geral">
    Conceitos, casos de uso e mapa de endpoints.
  </Card>

  <Card title="Venda rápida" icon="zap" href="/pt-BR/checkout/charges">
    Cobrança individual, sem template.
  </Card>

  <Card title="Webhooks" icon="webhook" href="/pt-BR/webhooks/visao-geral">
    Reconcilie por `transaction.paid` e `transaction.refused`.
  </Card>

  <Card title="Splits" icon="split" href="/pt-BR/splits">
    O modelo de divisão entre recebedores.
  </Card>
</CardGroup>
