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

# Fechar as cobranças extras agora

> Emite uma fatura separada com as cobranças extras pendentes da assinatura, sem esperar a virada do ciclo.

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

Faz parte do recurso [Assinaturas](/pt-BR/subscriptions). Os itens são criados em
[Lançar cobrança extra](/pt-BR/subscriptions/extra-items) e a fila inteira está em
[Listar cobranças extras](/pt-BR/subscriptions/extra-items-get).

Emite uma fatura avulsa com **todas** as cobranças extras `pending` da assinatura, sem esperar a
próxima fatura de ciclo — que, numa recorrência anual, pode estar a doze meses.

Os itens passam a `consumed`, com `consumedInvoiceId` apontando para a fatura emitida, e não entram
mais na fatura do ciclo. O contrato não muda: nem o ciclo, nem a data da próxima fatura, nem o valor
da mensalidade.

O corpo é opcional — as linhas e o valor vêm da fila. Sem corpo, a fatura vence hoje e a cobrança
dispara no ato.

## O vencimento decide quando a cobrança acontece

A fatura resultante é uma avulsa como qualquer outra: a cobrança dispara em
`dueAt - chargeLeadTimeDays` da assinatura. Com `dueAt` no futuro, a fatura nasce `scheduled`; sem
`dueAt`, nasce `open`.

O que acontece na abertura depende da forma de pagamento da assinatura:

| Forma de pagamento | Na abertura da fatura                                           |
| ------------------ | --------------------------------------------------------------- |
| Cartão             | O cartão salvo é cobrado. Nenhum e-mail é enviado               |
| PIX ou boleto      | Nada é cobrado: sai um e-mail com o link da página de pagamento |

<Warning>
  **Em PIX e boleto, um vencimento distante adia o e-mail.** O link é enviado quando a fatura abre —
  `chargeLeadTimeDays` antes do vencimento —, e não no momento desta chamada. Para que ele saia
  agora, omita o `dueAt`.
</Warning>

## Recusas

<Warning>
  **Fila vazia responde `409`.** Não há o que faturar quando nenhum item está `pending`.
</Warning>

Assinatura inexistente ou de outra conta responde `404`. `dueAt` no passado responde `400`.

## Depois de emitida

A fatura participa do split da assinatura, dispara os mesmos webhooks `invoice.*` e tem a mesma
página de pagamento hospedada. Cada item recolhido dispara um
[`extra_item.billed`](/pt-BR/webhooks/eventos).

**Anular a fatura devolve os itens para a fila** — eles voltam a `pending` e entram no próximo
fechamento, seja o do ciclo ou outra chamada desta rota.

## Exemplo

```bash theme={null}
curl -X POST https://api.sandbox.z2pay.com/v1/subscriptions/sub_x33m4yn6brazh71en4mki6f5c/extra-items/settle \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -H "Content-Type: application/json" \
  -d '{
    "dueAt": "2026-09-05T23:59:59.000Z",
    "reasonDetails": "Fechamento antecipado pedido pelo cliente"
  }'
```

```json Resposta 201 theme={null}
{
  "id": "inv_c3qahi4qnkc258lfc14gplupt",
  "number": { "year": 2026, "sequence": 128 },
  "customerId": "cust_c72q6ogr9iko0we85mqal04te",
  "customerEmail": "maria.silva@example.com",
  "customerName": "Maria Silva",
  "currency": "BRL",
  "subscriptionId": "sub_x33m4yn6brazh71en4mki6f5c",
  "status": "scheduled",
  "kind": "manual",
  "periodStart": null,
  "periodEnd": null,
  "chargeAt": "2026-09-05T23:59:59.000Z",
  "dueAt": "2026-09-05T23:59:59.000Z",
  "issuedAt": "2026-08-21T13:10:00.000Z",
  "subtotal": 34980,
  "total": 34980,
  "amountPaid": 0,
  "amountRemaining": 34980,
  "metadata": {
    "manualInvoice": true,
    "reason": "extra_items_settlement",
    "reasonDetails": "Fechamento antecipado pedido pelo cliente"
  },
  "createdAt": "2026-08-21T13:10:00.000Z"
}
```

<Note>
  **As linhas da fatura podem não estar disponíveis imediatamente.** O `total` desta resposta já é o
  definitivo; a composição aparece em `GET /invoices/{id}`, que pode devolver `items` vazio nos
  instantes seguintes. O webhook `invoice.issued` marca o momento em que ela está completa.
</Note>


## OpenAPI

````yaml openapi/billing.json POST /subscriptions/{id}/extra-items/settle
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/settle:
    post:
      tags:
        - Subscriptions
      summary: Fechar as cobranças extras agora
      description: >-
        Emite uma fatura avulsa com TODAS as cobranças extras `pending` da
        assinatura, sem esperar a próxima fatura de ciclo — que, numa
        recorrência anual, pode estar a doze meses.


        Os itens saem da fila (`status=consumed`, com `consumedInvoiceId`
        apontando para a fatura emitida) e não entram mais na fatura do ciclo. O
        contrato segue intacto: nem o ciclo, nem `nextInvoiceAt`, nem o valor da
        mensalidade mudam.


        A fatura resultante é uma avulsa como qualquer outra — cobra pelo método
        padrão da assinatura, dispara os mesmos webhooks `invoice.*` e, se for
        anulada, devolve os itens para a fila.


        Corpo opcional: sem ele, a fatura vence hoje e cobra no ato.
      operationId: SubscriptionController_settleExtraItems
      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:
                dueAt:
                  type: string
                  format: date-time
                  description: >-
                    Vencimento da fatura de fechamento (ISO 8601 com timezone),
                    estritamente no futuro. Ausente = vence hoje, e a cobrança
                    dispara no ato.
                reasonDetails:
                  type: string
                  minLength: 1
                  maxLength: 500
                  description: >-
                    Justificativa do fechamento antecipado, para a trilha de
                    auditoria (1 a 500 caracteres). Ausente = texto padrão. O
                    pagador não vê — o que ele vê é a `description` de cada
                    item.
                allowedPaymentMethods:
                  type: array
                  items:
                    type: string
                    enum:
                      - card
                      - pix
                      - boleto
                  minItems: 1
                  maxItems: 3
                  description: >-
                    Formas de pagamento oferecidas na página desta fatura.
                    Ausente = o método padrão da assinatura.
                installmentsConfig:
                  type: object
                  properties:
                    maxInstallments:
                      type: integer
                      minimum: 1
                      maximum: 12
                    freeInstallments:
                      type: integer
                      minimum: 1
                      maximum: 12
                    interestRate:
                      type: number
                      minimum: 0
                      maximum: 100
                  required:
                    - maxInstallments
                  nullable: true
                  description: >-
                    Parcelamento oferecido ao pagador no cartão — só faz sentido
                    com `card` em `allowedPaymentMethods`. Ausente/null = à
                    vista.
      responses:
        '201':
          description: Fatura de fechamento emitida
        '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: Resource not found
        '409':
          description: Não há cobrança extra pendente para fechar
          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)

````