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 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
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))