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

# Atualizar forma de pagamento

> Define por onde as próximas cobranças serão feitas — e ativa a assinatura, quando ela ainda não cobrava.

`POST /subscriptions/:id/payment-method`

Faz parte do recurso [Assinaturas](/pt-BR/subscriptions) — o conceito e os dez estados estão lá.

Troca a forma de pagamento padrão da assinatura. É também a única rota que tira uma assinatura de
`incomplete`.

<Warning>
  **A rota faz duas coisas diferentes, conforme o estado.**

  Em assinatura **ativa**, ela troca o meio de cobrança. Se for cartão novo, ele é validado com uma
  cobrança de **R\$ 1,23 estornada na hora** — recusado, a chamada responde `409` e a forma anterior
  **é mantida**.

  Em assinatura **`incomplete`**, ela **ativa** a assinatura e emite a primeira fatura imediatamente.
  Aqui não há cobrança de validação: quem valida o cartão é a própria fatura. Recusado, a assinatura
  continua `incomplete`.
</Warning>

<Note>
  **As três formas de informar:**

  * **cartão novo** — tokenize com o Tokenizer SDK e envie o `tok_` em `token`. O cartão é salvo na
    carteira do cliente antes de virar o padrão;
  * **cartão já salvo** — envie o `crd_` em `cardId`. Se não pertencer ao cliente da assinatura,
    responde `409`;
  * **PIX ou boleto** — só o `type`, sem `token` nem `cardId`.
</Note>

<Warning>
  **A rota tem limite de 20 chamadas por minuto na conta.** Cada cartão novo dispara uma validação
  real na adquirente, e sem o limite uma chave vazada viraria oráculo para testar cartões roubados.
  Uma troca de forma de pagamento legítima nunca chega perto disso.
</Warning>

<Note>
  **Assinatura em estado terminal recusa a troca.** `canceled`, `completed` e `incomplete_expired`
  respondem `409` — não há cobrança futura para configurar.
</Note>

<Note>
  **O link hospedado é outra coisa.** A Z2Pay hospeda uma página em que o **cliente final** troca o
  próprio cartão, sem passar pela sua integração. Ela não serve para ativar uma `incomplete`. Ver
  [Faturas](/pt-BR/subscriptions/invoices).
</Note>

## Exemplo

```bash theme={null}
curl -X POST https://api.sandbox.z2pay.com/v1/subscriptions/sub_x33m4yn6brazh71en4mki6f5c/payment-method \
  -H "x-api-key: SUA_CHAVE_DE_SANDBOX" \
  -H "Content-Type: application/json" \
  -d '{
    "paymentMethod": {
      "type": "card",
      "token": "tok_tvq2nzr8ymcx0kwbedhj4tapf"
    }
  }'
```

```json Resposta 200 theme={null}
{
  "id": "sub_x33m4yn6brazh71en4mki6f5c",
  "status": "active",
  "defaultPaymentMethodRef": {
    "type": "card",
    "id": "crd_j7x2wmb50qft9ndzalrey6cuk"
  },
  "currentPeriodEnd": "2026-09-10T12:00:00.000Z",
  "nextInvoiceAt": "2026-09-10T12:00:00.000Z",
  "updatedAt": "2026-08-10T17:12:40.000Z"
}
```

<Note>
  O `crd_` da resposta é o cartão materializado a partir do `tok_` enviado — o token é efêmero, o
  cartão salvo é permanente. O exemplo está abreviado; o playground mostra o corpo inteiro.
</Note>


## OpenAPI

````yaml openapi/billing.json POST /subscriptions/{id}/payment-method
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}/payment-method:
    post:
      tags:
        - Subscriptions
      summary: Atualizar forma de pagamento da assinatura
      description: >-
        Define a forma de pagamento padrão das próximas cobranças da assinatura.
        Em `paymentMethod`, informe o `type` e a referência do meio de
        pagamento:


        - **Cartão novo** — tokenize o cartão com o Tokenizer SDK (PCI) e envie
        o `tok_...` em `token`. O cartão é salvo permanentemente na carteira do
        cliente antes de virar o padrão.

        - **Cartão já salvo** — envie o `crd_...` de um cartão existente do
        cliente em `cardId` (precisa pertencer ao cliente da assinatura, senão
        `409`).

        - **PIX ou boleto** — `type: "pix"` ou `"boleto"`; sem `token`/`cardId`.


        Validação do cartão: em assinatura **ativa**, o cartão novo é validado
        com uma cobrança de R\$ 1,23 estornada na hora — se recusado, retorna
        `409` e a forma anterior é mantida. Em assinatura **incomplete**, esta
        chamada **ativa** a assinatura e emite a primeira fatura na hora (é ela
        que valida o cartão, sem a cobrança de validação) — se recusado, a
        assinatura continua incomplete.
      operationId: SubscriptionController_updatePaymentMethod
      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:
                paymentMethod:
                  type: object
                  properties:
                    type:
                      type: string
                      enum:
                        - card
                        - boleto
                        - pix
                      description: Tipo da forma de pagamento.
                    token:
                      type: string
                      nullable: true
                      description: >-
                        Cartão novo: token gerado pelo Tokenizer SDK (`tok_`).
                        Exclusivo com `cardId`.
                    cardId:
                      type: string
                      nullable: true
                      description: >-
                        Cartão já salvo do cliente (`crd_`), obtido em resposta
                        anterior. Exclusivo com `token`.
                  required:
                    - type
              required:
                - paymentMethod
      responses:
        '200':
          description: Forma de pagamento atualizada
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    description: Identificador único do registro.
                  number:
                    type: object
                    properties:
                      sequence:
                        type: integer
                        description: >-
                          Número sequencial do documento dentro da numeração
                          (assinatura ou fatura).
                    description: Número do endereço.
                  referenceCode:
                    type: string
                    description: >-
                      Código do contrato no sistema do integrador; pesquisável,
                      sem unicidade.
                    nullable: true
                  customerId:
                    type: string
                    description: ID do cliente associado ao registro.
                  customerEmail:
                    type: string
                    description: E-mail do cliente.
                  customerName:
                    type: string
                    description: Nome do cliente.
                  customerDocument:
                    type: string
                    description: Documento do cliente (CPF ou CNPJ).
                  currency:
                    type: string
                    description: 'Moeda no padrão ISO 4217 (ex.: BRL).'
                  status:
                    type: string
                    enum:
                      - incomplete
                      - incomplete_expired
                      - trialing
                      - active
                      - past_due
                      - unpaid
                      - paused
                      - canceled
                      - completed
                    description: >-
                      Status atual do registro (assinatura, fatura, plano ou
                      slip de pagamento).
                  billingGroupId:
                    nullable: true
                    description: >-
                      ID do grupo de cobrança ao qual o registro pertence; nulo
                      se não agrupado.
                  currentPeriodStart:
                    type: string
                    format: date-time
                    description: >-
                      Início do período de cobrança atual da assinatura (ISO
                      8601).
                  currentPeriodEnd:
                    type: string
                    format: date-time
                    description: Fim do período de cobrança atual da assinatura (ISO 8601).
                  nextInvoiceAt:
                    type: string
                    format: date-time
                    description: >-
                      Data e hora prevista para a próxima fatura da assinatura
                      (ISO 8601).
                    nullable: true
                  recurrence:
                    type: object
                    properties:
                      interval:
                        type: integer
                        description: >-
                          Quantidade de unidades por ciclo de cobrança (ex.:
                          interval 3 + unit month = trimestral).
                      unit:
                        type: string
                        description: >-
                          Unidade do ciclo de cobrança: day, week, month ou
                          year.
                      anchor:
                        type: string
                        description: >-
                          Âncora que fixa a data de renovação do ciclo:
                          subscription_start, day_of_month ou end_of_month.
                      anchorDay:
                        type: integer
                        description: >-
                          Dia do mês (1–31) usado quando a âncora é
                          day_of_month.
                      collectionTiming:
                        type: string
                        description: >-
                          Momento da cobrança do ciclo: prepaid (no início) ou
                          postpaid (no fim).
                    description: >-
                      Regra de recorrência (intervalo, unidade e âncora do
                      ciclo).
                  collectionMethod:
                    type: string
                    enum:
                      - charge_automatically
                    description: >-
                      Como a fatura é cobrada. Hoje só a cobrança automática na
                      forma de pagamento padrão.
                  collectionTiming:
                    type: string
                    enum:
                      - prepaid
                      - postpaid
                    description: >-
                      Momento da cobrança do ciclo: prepaid (no início) ou
                      postpaid (no fim).
                  invoiceGenerationMode:
                    type: string
                    enum:
                      - just_in_time
                      - upfront
                    description: >-
                      Modo de geração de faturas: just_in_time (a cada ciclo) ou
                      upfront (todas antecipadas).
                  cancelAtPeriodEnd:
                    type: boolean
                    description: >-
                      Indica se a assinatura será cancelada ao fim do período
                      atual.
                  canceledAt:
                    nullable: true
                    description: >-
                      Data e hora do cancelamento; nula se não cancelado (ISO
                      8601).
                  endedAt:
                    nullable: true
                    description: >-
                      Data e hora em que a assinatura foi efetivamente
                      encerrada; nula se ainda ativa (ISO 8601).
                  cancellationReason:
                    nullable: true
                    description: Motivo do cancelamento da assinatura.
                  pausedAt:
                    nullable: true
                    description: >-
                      Data e hora em que a assinatura foi pausada; nula se não
                      pausada (ISO 8601).
                  pauseResumesAt:
                    nullable: true
                    description: >-
                      Data e hora agendada para a retomada automática da
                      assinatura pausada (ISO 8601).
                  pauseReason:
                    nullable: true
                    description: Motivo da pausa da assinatura.
                  trialEnd:
                    nullable: true
                    description: >-
                      Data e hora de término do período de teste; nula se sem
                      trial (ISO 8601).
                  incompleteExpiresAt:
                    nullable: true
                    description: >-
                      Prazo para concluir o primeiro pagamento antes de a
                      assinatura incompleta expirar (ISO 8601).
                  trialRemindersFired:
                    type: array
                    items: {}
                    description: >-
                      Lembretes de fim do período de teste já disparados para a
                      assinatura.
                  maxCycles:
                    type: integer
                    description: >-
                      Número máximo de ciclos da assinatura; nulo se não houver
                      limite.
                    nullable: true
                  issuedCycles:
                    type: integer
                    description: >-
                      Número de ciclos já faturados (faturas emitidas) da
                      assinatura.
                  completedCycles:
                    type: integer
                    description: Número de ciclos já concluídos (pagos) da assinatura.
                  defaultPaymentMethodRef:
                    type: object
                    properties:
                      id:
                        type: string
                        description: Identificador único do registro.
                        nullable: true
                      type:
                        type: string
                        description: >-
                          Tipo da referência: meio da forma de pagamento (card,
                          pix, boleto) ou natureza da linha da fatura.
                    description: >-
                      Referência da forma de pagamento padrão usada para cobrar
                      a assinatura.
                  splitConfig:
                    nullable: true
                    description: >-
                      Configuração de divisão (split) dos valores entre
                      recebedores; nula se sem split.
                  paymentBehavior:
                    type: string
                    enum:
                      - allow_incomplete
                      - error_if_incomplete
                    description: >-
                      O que fazer quando a primeira cobrança não é aprovada:
                      allow_incomplete cria a assinatura com a fatura em aberto;
                      error_if_incomplete cancela a assinatura.
                  latestInvoiceId:
                    type: string
                    description: ID da fatura mais recente gerada pela assinatura.
                  paymentUpdateToken:
                    nullable: true
                    description: >-
                      Token do link público para o cliente atualizar a forma de
                      pagamento; nulo se não gerado.
                  paymentUpdateMethods:
                    nullable: true
                    description: >-
                      Formas de pagamento permitidas no link público de troca;
                      nula se não habilitada.
                  metadata:
                    type: object
                    properties: {}
                    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).
                  items:
                    type: array
                    description: Itens que a assinatura cobra.
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          description: Identificador único do registro.
                        subscriptionId:
                          type: string
                          description: ID da assinatura relacionada ao registro.
                        planItemId:
                          type: string
                          description: >-
                            ID do componente (plan item) ao qual o preço se
                            refere.
                          nullable: true
                        priceVersionId:
                          type: string
                          description: ID da versão de preço aplicada ao item.
                          nullable: true
                        name:
                          type: string
                          nullable: true
                          description: >-
                            O que se cobra. Vem do item do plano, ou da
                            descrição do item avulso.
                        unitAmount:
                          type: integer
                          description: Valor unitário do item, em centavos.
                        quantity:
                          type: integer
                          description: Quantidade do item.
                        addedAt:
                          type: string
                          format: date-time
                          description: >-
                            Data e hora em que o item foi adicionado à
                            assinatura (ISO 8601).
                        removedAt:
                          nullable: true
                          description: >-
                            Data e hora em que o item foi removido da
                            assinatura; nula se ainda ativo (ISO 8601).
              example:
                id: sub_hsm2kigu74htdxj3nw2z6f9xw
                number:
                  sequence: 42
                referenceCode: CONTRATO-2026-0042
                customerId: cust_c72q6ogr9iko0we85mqal04te
                customerEmail: maria.silva@example.com
                customerName: Maria Silva
                customerDocument: '12345678909'
                currency: BRL
                status: active
                billingGroupId: null
                currentPeriodStart: '2025-06-01T03:00:00.000Z'
                currentPeriodEnd: '2025-07-01T03:00:00.000Z'
                nextInvoiceAt: '2025-07-01T03:00:00.000Z'
                recurrence:
                  interval: 1
                  unit: month
                  anchor: day_of_month
                  anchorDay: 1
                  collectionTiming: prepaid
                collectionMethod: charge_automatically
                collectionTiming: prepaid
                invoiceGenerationMode: just_in_time
                cancelAtPeriodEnd: false
                canceledAt: null
                endedAt: null
                cancellationReason: null
                pausedAt: null
                pauseResumesAt: null
                pauseReason: null
                trialEnd: null
                incompleteExpiresAt: null
                trialRemindersFired: []
                maxCycles: 12
                issuedCycles: 1
                completedCycles: 1
                defaultPaymentMethodRef:
                  id: crd_tsj66oabsygc9kwvvzt8189f9
                  type: card
                splitConfig: null
                paymentBehavior: allow_incomplete
                latestInvoiceId: inv_c3qahi4qnkc258lfc14gplupt
                paymentUpdateToken: null
                paymentUpdateMethods: null
                metadata: {}
                createdAt: '2025-06-01T13:45:30.000Z'
                updatedAt: '2025-06-01T13:45:30.000Z'
                items:
                  - id: subi_k9m3xqr7wt2zpf5hnc8ydv4bj
                    subscriptionId: sub_hsm2kigu74htdxj3nw2z6f9xw
                    planItemId: pli_hqx9z6jinrx1arv96nb5xus4p
                    priceVersionId: price_t4wz8hqm2xkcr9pfs5ynd3vbj
                    name: Assinatura base
                    unitAmount: 9990
                    quantity: 1
                    addedAt: '2025-06-01T13:45:30.000Z'
                    removedAt: null
        '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 ou cartão não encontrado
          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: >-
            Cartão recusado, violação de ownership ou assinatura 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)

````