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

# Lançar cobrança extra

> Enfileira um item avulso que entra na próxima fatura de ciclo da assinatura, junto da mensalidade.

`POST /subscriptions/:id/extra-items`

Faz parte do recurso [Assinaturas](/pt-BR/subscriptions) — o conceito e os dez estados estão lá. As
faturas que essa fila alimenta são o recurso [Faturas](/pt-BR/subscriptions/invoices).

Cria um item com `description`, `amount` (centavos) e `quantity` opcional (default `1`). O item não
gera cobrança nem fatura própria: fica `pending` até a próxima fatura de ciclo recolhê-lo, como uma
linha `one_time` ao lado da mensalidade.

Para cobrar antes da virada do ciclo há dois caminhos:
[criar uma fatura avulsa](/pt-BR/subscriptions/invoices/create), que é uma cobrança separada com
vencimento próprio, ou [fechar a fila inteira agora](/pt-BR/subscriptions/extra-items-settle), que
emite uma fatura com tudo que está pendente.

<Note>
  **Prepaid ou postpaid decide qual fatura recolhe o item, não se ele será cobrado.** Em cobrança
  antecipada (o padrão), a fatura do ciclo corrente já foi emitida quando você lança o item — ele
  espera o ciclo seguinte. Em cobrança postecipada, a fatura do ciclo corrente só fecha no fim do
  período — um item lançado a qualquer momento durante esse período ainda entra nela.
</Note>

<Note>
  **Cancelar a assinatura não descarta a fila.** O que ainda está `pending` no momento do
  cancelamento vira uma fatura avulsa final, uma linha por item — pela mesma régua que decide o
  destino das faturas vencidas em [`cancel`](/pt-BR/subscriptions/cancel): com
  `keepOverdueInvoices: false`, as vencidas e a fila são descartadas juntas.
</Note>

## Exemplo

```bash theme={null}
curl -X POST https://api.sandbox.z2pay.com/v1/subscriptions/sub_x33m4yn6brazh71en4mki6f5c/extra-items \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Segunda via da carteirinha",
    "amount": 4990,
    "quantity": 1,
    "reason": "extra_service",
    "reasonDetails": "Cliente perdeu a carteirinha e pediu a segunda via"
  }'
```

```json Resposta 201 theme={null}
{
  "id": "xitm_xusdt7vquv0sjrj8k6er6xn6y",
  "description": "Segunda via da carteirinha",
  "amount": 4990,
  "quantity": 1,
  "currency": "BRL",
  "reason": "extra_service",
  "reasonDetails": "Cliente perdeu a carteirinha e pediu a segunda via",
  "status": "pending",
  "consumedInvoiceId": null,
  "createdAt": "2026-08-10T18:20:00.000Z"
}
```


## OpenAPI

````yaml openapi/billing.json POST /subscriptions/{id}/extra-items
openapi: 3.0.3
info:
  title: Z2Pay Billing API
  version: 1.0.0
  description: Cobrança recorrente da Z2Pay — planos, assinaturas e faturas
servers:
  - url: https://api.sandbox.z2pay.com/v1
    description: Sandbox
  - url: https://api.z2pay.com/v1
    description: Produção
security: []
tags:
  - name: Invoices
    description: Faturas emitidas pelas assinaturas
  - name: Plans
    description: Planos de cobrança e versões de preço
  - name: Subscriptions
    description: Assinaturas recorrentes
paths:
  /subscriptions/{id}/extra-items:
    post:
      tags:
        - Subscriptions
      summary: Lançar cobrança extra
      description: >-
        Lança uma cobrança avulsa na fila da assinatura — **não gera cobrança
        imediata nem fatura separada**: o item entra na PRÓXIMA fatura de ciclo,
        junto da mensalidade. Um item lançado no instante exato do fechamento
        cai na fatura seguinte, nunca na que está fechando. Assinaturas em
        contrato `upfront` recusam o lançamento, porque todas as faturas já
        nasceram `scheduled` — use uma fatura avulsa. Estados terminais
        (`canceled`/`completed`/`incomplete_expired`) também recusam, porque não
        geram mais fatura; os demais estados aceitam.
      operationId: SubscriptionController_createExtraItem
      parameters:
        - name: id
          in: path
          required: true
          description: ID da assinatura
          schema:
            type: string
        - name: Idempotency-Key
          in: header
          required: false
          description: Chave única para garantir idempotência da requisição
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                description:
                  type: string
                  minLength: 1
                  maxLength: 255
                  description: O que está sendo cobrado (aparece na linha da fatura).
                amount:
                  type: integer
                  minimum: 0
                  exclusiveMinimum: true
                  description: >-
                    Valor unitário, em centavos (menor unidade da moeda). A
                    moeda é a da assinatura.
                quantity:
                  type: integer
                  minimum: 1
                  default: 1
                  description: >-
                    Quantidade. Default `1` — o total lançado é `amount *
                    quantity`.
                reason:
                  type: string
                  enum:
                    - extra_service
                    - adjustment
                    - penalty
                    - other
                  description: >-
                    Classificação da cobrança, para auditoria e relatório. Mesmo
                    vocabulário da fatura avulsa, sem `ad_hoc` — um item que
                    entra na fatura do ciclo não é avulso.
                reasonDetails:
                  type: string
                  minLength: 1
                  maxLength: 500
                  description: >-
                    Justificativa em texto livre (1 a 500 caracteres). Fica na
                    trilha de auditoria do lançamento, não aparece na fatura do
                    pagador — o que o pagador vê é `description`.
              required:
                - description
                - amount
                - reason
                - reasonDetails
      responses:
        '201':
          description: Cobrança extra lançada, com status `pending`
        '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
        '404':
          description: Assinatura não encontrada
          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: NOT_FOUND
                  message: Subscription not found
        '409':
          description: Assinatura em contrato upfront ou em estado terminal
          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: CONFLICT
                  message: No refundable payment found
        '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 da Credential (gerada no Backoffice)

````