Pix Automático (Recorrência)

Este guia mostra o fluxo de Pix Automático — recorrência (rec), solicitação de confirmação (solicrec) e cobranças recorrentes (cobr) — com ênfase no cancelamento, que é a operação onde mais se erra o valor do status.

Note

Para cobranças com data de vencimento sem recorrência (cobv), veja Cobranças com Vencimento.

Status disponíveis

Os status são definidos pela especificação do BACEN e valem para todos os PSPs (Banco do Brasil, Sicoob e Sicredi). A biblioteca expõe todos eles como enums:

from pypix_api.models.enums import (
    PoliticaRetentativa,
    StatusCob,
    StatusCobR,
    StatusRec,
    StatusSolicRec,
)

Enum

Valores

Aceito em PATCH

StatusCob

ATIVA, CONCLUIDA, REMOVIDA_PELO_USUARIO_RECEBEDOR, REMOVIDA_PELO_PSP

REMOVIDA_PELO_USUARIO_RECEBEDOR

StatusCobR

CRIADA, ATIVA, CONCLUIDA, EXPIRADA, REJEITADA, CANCELADA

CANCELADA

StatusRec

CRIADA, APROVADA, REJEITADA, EXPIRADA, CANCELADA

CANCELADA

StatusSolicRec

CRIADA, ENVIADA, RECEBIDA, REJEITADA, ACEITA, EXPIRADA, CANCELADA

CANCELADA

Os demais valores são atribuídos pelo PSP e só aparecem em respostas ou como filtro em listagens. Em particular, REJEITADA nunca deve ser enviado em uma revisão — é a decisão do PSP do pagador.

Fluxo completo

As três etapas são encadeadas: a recorrência (rec) estabelece o vínculo, a solicitação (solicrec) leva esse vínculo ao pagador para autorização, e só então as cobranças (cobr) de cada ciclo podem ser liquidadas. Pular o solicrec deixa a recorrência parada em CRIADA.

import uuid
from datetime import date, timedelta

from pypix_api.auth.oauth2 import OAuth2Client
from pypix_api.banks.sicredi import SicrediPixAPI
from pypix_api.models.enums import PoliticaRetentativa, StatusRec
from pypix_api.utils.identificadores import gerar_id_rec

oauth = OAuth2Client(
    token_url=SicrediPixAPI.TOKEN_URL,
    client_id='seu_client_id',
    client_secret='seu_client_secret',
    cert='certificado.pem',
    pvk='chave.key',
)
api = SicrediPixAPI(oauth=oauth)

# 1. Criar a recorrência (o vínculo com o pagador)
#    O idRec tem regra de formação semântica — veja a seção abaixo.
politica = PoliticaRetentativa.PERMITE_3R_7D
id_rec = gerar_id_rec(ispb='12345678', politica_retentativa=politica)

rec = api.criar_recorrencia({
    'idRec': id_rec,
    'vinculo': {
        'contrato': 'CT-2026-0001',
        'devedor': {'cpf': '12345678909', 'nome': 'Fulano de Tal'},
        'objeto': 'Assinatura mensal',
    },
    'calendario': {
        'dataInicial': str(date.today() + timedelta(days=7)),
        'periodicidade': 'MENSAL',
    },
    'valor': {'valorRec': '49.90'},
    'politicaRetentativa': politica.value,
    'ativacao': {'dadosJornada': {'txid': uuid.uuid4().hex}},
})

# 2. Solicitar a confirmação ao pagador
#    Sem esta etapa a recorrência permanece CRIADA e não é autorizada.
solic = api.criar_solicrec({
    'idRec': id_rec,
    'calendario': {
        'dataExpiracaoSolicitacao': (
            f'{date.today() + timedelta(days=3)}T23:59:59Z'
        ),
    },
    'destinatario': {
        'ispbParticipante': '91193552',
        'agencia': '2569',
        'conta': '550689',
        'cpf': '12345678909',
    },
})
id_solic_rec = solic['idSolicRec']

# 3. Acompanhar até o pagador aceitar (status ACEITA) e a rec ficar APROVADA
#    Na prática, use o webhook de recorrência em vez de consultar em laço.
if api.consultar_recorrencia(id_rec)['status'] == StatusRec.APROVADA:
    ...

# 4. Emitir uma cobrança do ciclo
txid = uuid.uuid4().hex
cobr = api.criar_cobr_com_txid(txid, {
    'idRec': id_rec,
    'calendario': {'dataDeVencimento': str(date.today() + timedelta(days=10))},
    'valor': {'original': '49.90'},
    'recebedor': {'agencia': '1234', 'conta': '567890', 'tipoConta': 'CORRENTE'},
    'ajusteDiaUtil': True,
})

O identificador da recorrência (idRec)

O idRec não é um identificador livre. O schema RecId define uma regra de formação com significado em cada trecho:

RAxxxxxxxxyyyyMMddkkkkkkkkkkk   (29 caracteres, case sensitive)

R           fixo, recorrência criada dentro do Pix
A           'R' permite retentativa pós-vencimento, 'N' não permite
xxxxxxxx    ISPB do participante (8 dígitos)
yyyyMMdd    data de criação da recorrência
kkkkkkkkkkk sequencial alfanumérico (11 caracteres), único no dia

Warning

Um valor aleatório de 29 caracteres alfanuméricos passa na validação de formato do schema (pattern: [a-zA-Z0-9]{29}) e ainda assim é recusado pelo PSP, porque o ISPB e a data precisam ser reais. Da mesma forma, o segundo caractere precisa ser coerente com politicaRetentativa: usar RR (permite) junto de NAO_PERMITE gera uma contradição que nenhum schema detecta.

Use gerar_id_rec(), que deriva o segundo caractere da própria política, eliminando a inconsistência:

from pypix_api.models.enums import PoliticaRetentativa
from pypix_api.utils.identificadores import gerar_id_rec

gerar_id_rec('12345678', PoliticaRetentativa.PERMITE_3R_7D)
# 'RR12345678' + data de hoje + sequencial aleatório

gerar_id_rec('12345678', PoliticaRetentativa.NAO_PERMITE)
# 'RN12345678' + data de hoje + sequencial aleatório

# Com sequencial e data explícitos (quando há controle transacional)
gerar_id_rec(
    ispb='12345678',
    politica_retentativa=PoliticaRetentativa.PERMITE_3R_7D,
    data_criacao=date(2026, 7, 25),
    sequencial='abcdefghijk',
)
# 'RR1234567820260725abcdefghijk'

O ispb é o do participante direto ou indireto, ou os 8 primeiros dígitos do CNPJ do prestador de serviço de iniciação — obtenha-o com seu PSP. O sequencial gerado automaticamente é aleatório entre 62^11 combinações; se a aplicação tiver controle transacional, informe-o explicitamente para garantir unicidade no dia.

Cancelar uma cobrança sem cancelar a recorrência

Esta é a distinção que mais gera confusão. São recursos diferentes:

# Cancela SOMENTE a cobrança deste ciclo.
# A recorrência segue ativa e os próximos ciclos continuam sendo cobrados.
api.cancelar_cobr(txid)

# Encerra a recorrência INTEIRA, incluindo as cobranças futuras.
api.cancelar_recorrencia(id_rec)

# Cancela a solicitação de confirmação enviada ao pagador.
api.cancelar_solicrec(id_solic_rec)

Os três helpers são atalhos para os métodos revisar_*, que também podem ser chamados diretamente com o corpo montado à mão:

from pypix_api.models.enums import StatusCobR

api.revisar_cobr(txid, {'status': StatusCobR.CANCELADA.value})

O corpo é plano e tem um único campo — o schema CobRStatusRevisada não aceita nenhum outro:

{"status": "CANCELADA"}

Warning

O PSP recusa o cancelamento com HTTP 400 quando a data corrente é igual ou posterior à data prevista da primeira tentativa de liquidação. Não existe janela em dias — o corte é essa data. Cancele antes que o ciclo entre em liquidação.

Uma CobR CANCELADA (ou REJEITADA) libera o ciclo, permitindo emitir uma nova cobrança para o mesmo idRec com a mesma dataDeVencimento.

Consultar o status

Como os enums herdam de str, a comparação com a resposta crua da API funciona diretamente:

from pypix_api.models.enums import StatusCobR

cobr = api.consultar_cobr(txid)

if cobr['status'] == StatusCobR.CANCELADA:
    print('Cobrança cancelada')
elif cobr['status'] == StatusCobR.CONCLUIDA:
    print('Cobrança liquidada')

Retentativa

Só é possível solicitar retentativa se a recorrência tiver sido criada com PoliticaRetentativa.PERMITE_3R_7D (até 3 retentativas em até 7 dias):

api.solicitar_retentativa_cobr(txid, date.today() + timedelta(days=2))