Pular para o conteúdo.

Homologação — artefatos e como reproduzir

Esta pasta guarda o resultado da homologação dos três bancos, não o processo. O formulário é do C6; o que é nosso são as decisões de escopo e a evidência. Sicoob e Inter seguem o mesmo roteiro, sem formulário do banco.

Arquivo O que é
(formulário preenchido) Não é versionado: é documento de envio ao banco, gerado por preencher_roteiro_c6.py a partir da evidência JSON — regenerável a qualquer momento
evidencia-sandbox-c6.json A evidência crua do C6 — status HTTP e corpo de cada caso, como o banco devolveu
evidencia-sandbox-sicoob.json A evidência crua do Sicoob (veja a ressalva abaixo)
evidencia-sandbox-inter.json A evidência crua do Banco Inter — 13 casos em 2xx, zero falhas, com o banco ecoando o que foi enviado

O que cada sandbox prova — e a diferença não é detalhe

Banco Comportamento do sandbox O que a evidência atesta
C6 Real Integração ponta a ponta
Inter Real, verificado — a sonda de eco gravou sandbox_ecoa_o_enviado: true Integração ponta a ponta
Sicoob Mock de schema — cada caso carrega mock_do_banco: true Roteamento, contrato e normalização

Ler as três como equivalentes seria o erro caro: no Sicoob nenhum boleto foi registrado e nenhum Pix foi criado.

Sicoob — o que o roteiro dele prova, e o que não prova

scripts/homologacao_sicoob.py segue o mesmo molde do C6: cada caso é uma requisição HTTP às rotas do gateway. Mas o sandbox do Sicoob é mock de schema — devolve dados aleatórios válidos, sem relação com o que foi enviado. Pedindo uma cob de R$ 1,00 em 04/08/2026 ele respondeu valor: "0.39", pixCopiaECola: "ex do consectetur enim magna" e expiração em 2008.

Então essa evidência atesta roteamento, contrato e normalização; não atesta comportamento do banco. Nenhum boleto é de fato registrado, nenhum Pix é de fato criado. Cada caso carrega mock_do_banco: true para que ninguém leia mais do que está lá.

Onde o C6 provou integração ponta a ponta, aqui a prova é de contrato — e ainda assim valeu: o roteiro do Sicoob achou dois defeitos que o do C6 não podia achar (a conta ausente nas rotas de leitura e o estouro no cálculo de prazo).

Última execução: 14 casos em 2xx, 5 ausentes, 1 recusa — a recusa é a emissão, que no mock responde 400 enlatado com "string" no lugar da mensagem.

Formulário em branco: portal do C6 (etapa 4 do get-started). Não é versionado aqui — é material do banco, sujeito a atualização por eles.

Reproduzir

Dentro da janela do sandbox — seg-sex, 7h-23h BRT, fora dela o POST /v1/auth responde 403 e não é credencial inválida:

export C6_SANDBOX_CLIENT_ID=... C6_SANDBOX_CLIENT_SECRET=...
export C6_SANDBOX_PFX_BASE64=... C6_SANDBOX_PFX_PASSWORD=...
export C6_SANDBOX_CHAVE_PIX=...

PYTHONPATH=gateway python scripts/homologacao_c6.py --json > evidencia.json
python scripts/preencher_roteiro_c6.py evidencia.json --roteiro "<docx do portal>" \
    --cnpj "..." --empresa "..." --software "..." \
    --responsavel "..." --email "..." --telefone "..."

Os seis argumentos finais preenchem a tabela DADOS DA ORGANIZAÇÃO — são cadastro, não evidência, por isso entram na linha de comando. Os checkboxes de “APIs que você testará” saem da própria evidência: API com caso executado é marcada; API cujos casos são todos fora de escopo fica desmarcada. Corpo de resposta acima de 4.000 caracteres entra cortado nos 4.000 com a marcação [TRUNCADO — …] — a evidência JSON guarda o corpo inteiro.

Aceita identificadores de caso como argumento para rodar só um pedaço — homologacao_c6.py B_01 B_05.

Sicoob e Inter, mesmo molde e mesmos argumentos — o que muda é a credencial:

export SICOOB_SANDBOX_CLIENT_ID=... SICOOB_SANDBOX_ACCESS_TOKEN=...
PYTHONPATH=gateway python scripts/homologacao_sicoob.py --json > evidencia-sicoob.json

export INTER_SANDBOX_CLIENT_ID=... INTER_SANDBOX_CLIENT_SECRET=...
export INTER_SANDBOX_CERT_PEM="$(cat Sandbox_InterAPI_Certificado.crt)"
export INTER_SANDBOX_KEY_PEM="$(cat Sandbox_InterAPI_Chave.key)"
PYTHONPATH=gateway python scripts/homologacao_inter.py --json > evidencia-inter.json

O do Inter roda uma sonda de eco a cada execução: compara seuNumero, valor e vencimento enviados com os que voltaram, e publica o veredito em sandbox_ecoa_o_enviado. É ela que autoriza o relatório a afirmar integração ponta a ponta em vez de só contrato — se o banco trocar o ambiente por um mock, o campo vira false no mesmo instante.

O runner exercita a API, não o provider. Cada caso é uma requisição HTTP às rotas do gateway — router, schema, validação, exige_capacidade e tradução de erro incluídos. É o serviço que está sendo homologado; chamar C6Provider direto pularia exatamente a camada que o integrador enxerga, e o relatório atestaria uma coisa enquanto o cliente consome outra.

Sem --base-url, a app roda em processo (ASGI) — mesma pilha de rotas, só não cruza um socket. Com --base-url https://..., vai contra uma instância real.

O corpo registrado é a resposta da API, que carrega a do banco em raw — estritamente mais evidência do que o retorno cru do C6.

Nenhum dos dois scripts aceita retorno na linha de comando. É deliberado: o documento vai ao banco como atestado de teste, e não deve existir caminho em que alguém digite um corpo que a API não devolveu.

Uma exceção declarada: C_05_01 reentrega na nossa rota de webhook o corpo que o banco devolveu em C_01 — não há URL pública neste ambiente para o sandbox chamar de volta. O corpo entregue é do banco e o retorno registrado é da API; o que muda é quem fez a chamada, e está dito no documento.

Resultado da execução — C6

Última execução: 04/08/2026, contra o sandbox.

  Tabelas
Retorno 2xx do banco 50
Recusa do banco, com o corpo do erro 4
Marcadas N/A com o motivo 14, hoje 13
Em branco 0
Total do formulário 68

P_03_02 saiu dos N/A depois desta execução. Ele era ausente porque revisar_lote_cobv existia no mixin BACEN e o router não expunha; a rota PATCH /pix/lote/{id} fechou a lacuna, e o caso passa a ser executável. Os números da tabela são os da rodada de 04/08 e não foram remedidos — a próxima execução é que dirá se o banco aceita.

O formulário tem 68 tabelas de retorno, não 51. Ele usa duas formas — Pix Automático e BP_01 trazem um subtítulo entre o título e o cabeçalho — e o preenchedor lia só a primeira, deixando 17 tabelas fora da conta e em branco. Corrigido; a contagem acima é sobre o formulário inteiro.

O código de criação é 201 com Location, salvo o lote de cobv, que é 202 — o banco responde “lote solicitado para criação”, e o lote é enfileirado, não criado.

Resultado da execução — Banco Inter

13 casos em 2xx, zero falhas, 3 ausentes. O sandbox tem comportamento real: a sonda de eco confirmou que seuNumero, valor e vencimento voltam idênticos ao que foi enviado.

Os três ausentes, e o motivo de cada um:

Caso Por quê
PG_01 — pagamentos Fora de escopo. Saída de dinheiro; a régua de escopo exclui pagamento em qualquer provider
PA_01 — Pix Automático Produto não habilitado na conta. O provider implementa (dialeto BACEN, herdado do mixin) e GET /bancos declara a capacidade — o que falta é contratação, não código
SA_01 — saldo Rota não exposta pelo gateway; o extrato cobre o caso de uso

Dois defeitos nossos só apareceram aqui, contra o banco de verdade: a emissão voltava 502 por causa da barra final no path (o Inter responde 307 onde o C6 exige a barra), e o default formasRecebimento: BOLETO suprimia o QR Pix — o híbrido é BOLETO_PIX, hoje o default.

O certificado do sandbox expira em 03/09/2026. Vencido, toda chamada falha na autenticação e responde 424 — que é o diagnóstico certo, mas convém não descobrir pelo alerta do cliente.

Escopo — o que foi marcado e o que não foi

O banco manda não marcar o checkbox de API que a aplicação não usa. Das nove, sete estão marcadas. As 13 tabelas N/A se dividem em três motivos, e a diferença importa — só o primeiro é decisão de produto:

Caso Motivo
AP_01…AP_06 — Agendamento de pagamentos / DDA Fora de escopo. Saída de dinheiro; o produto é cobrança (entrada), e a régua de escopo exclui pagamento em qualquer provider
P_04_01…P_04_04 — Gerenciamento de location Fora de escopo. O gateway consome a location que a cob devolve; não gerencia o recurso
P_05_01, P_05_03, P_05_04 — Pix recebido e devolução Limite do ambiente, mesma família do C_05_02. A conta sandbox nunca recebeu Pix: GET /pix responde 200 com lista vazia até em janela de 180 dias, e o único lançamento do extrato é uma tarifa. Não há como gerar a massa por API — a de Agendamento de Pagamentos do C6 não executa pagamento, apenas enfileira para aprovação manual no internet banking. As rotas existem e estão cobertas por test_pix_recebidos_e_devolucao

O que o sandbox não deixou concluir

Quatro casos foram executados e não fecharam em 2xx. Nenhum é defeito de integração, e isso precisa estar dito no e-mail ao banco:

Caso O que aconteceu
C_05_02 — Evento de pagamento de link 403 do próprio banco. O evento nasce do pagamento na página hospedada do C6, e essa página não abre: payment-h.c6pay.com.br responde 403 (Cloudflare, “Sorry, you have been blocked”) na URL do checkout e na raiz do domínio, de navegador e de curl. A API cria o link e o banco devolve a URL — falta o acesso à página. Não é N/A: o caso está no escopo e implementado (checkout.atualizado → liquidado, com teste), e marcá-lo “não se aplica” esconderia um defeito do C6 atrás da nossa declaração de escopo
P_03_01, P_03_03, P_03_04 — lote de cobv 502 do próprio banco, em PUT e em GET. Isolado: o id do lote foi testado em 20, 26, 30 e 35 caracteres (a spec exige [a-zA-Z0-9]{26,35}) e o payload confere com o exemplo loteCobVBody1 da própria documentação; /cob, /cobv e /pix respondem 200 na mesma conexão, mesmo token e mesma janela. O corpo do 502 é HTML de Cloudflare, e a spec do C6 nem documenta 502 — só 400, 403, 404 e 503

A recusa também é evidência. A operação foi tentada e o banco respondeu; o corpo do erro está no documento, não um campo vazio.

B_04, B_08 e BP_04 — alterar, baixar e cancelar — dependem de a CIP ter aprovado o registro e oscilam entre execuções: numa rodada responderam 409/“já existe uma requisição à CIP sujeita a aprovação” mesmo após ~25 min de re-tentativa, na seguinte fecharam em 2xx. É o assíncrono do banco, descrito em c6-rest.md; o roteiro re-tenta e ainda faz uma repescagem no fim, mas quem decide é a CIP.

Defeito no formulário v3.0 do banco

Vale mencionar ao C6 — duas tabelas carregam o identificador da seção anterior, e o bloco de checkout escreve os sub-passos sem separador:

Tabela Rótulo no formulário O que a tabela realmente é
75 P_02_03 Consultar lote específico → P_03_03 (seção P_03 – Cobrança Pix em lote)
85 P_02_04 Desvincular cobrança de uma location → P_04_04 (seção P_04 – Gerenciamento de location)
45, 47 C_0501, C_0502 C_05_01 e C_05_02 — sem o _, os dois viram C_05 e colidem

O preenchedor corrige as duas primeiras por índice, que é o que identifica a tabela de fato, e continua avisando se aparecer outra repetição. Casar só pelo identificador faria a segunda tabela disputar a evidência da primeira — e ficar vazia sem explicação.

Re-sondar os casos não finalizados

O C6 avisou que está ajustando o sandbox. Como sete dos oito casos abertos dependem do banco ou do ambiente — não há o que corrigir do nosso lado, só descobrir quando destravam —, o retrabalho é reexecutar só esses casos quando o banco disser que mexeu:

# com as credenciais do sandbox já exportadas (ver "Reproduzir", acima)
PYTHONPATH=gateway python scripts/homologacao_c6.py --json \
  C_01 P_03_01 P_03_02 P_03_03 P_03_04 \
  P_05_02 P_05_01 P_05_03 P_05_04 C_05_02 \
  > "sonda-$(date -u +%F).json"

C_01 e P_05_02 não são o que se mede: são pré-condição. C_01 cria o checkout que C_05_02 sonda e P_05_02 popula o e2eid das consultas de Pix recebido — sem eles os N/F falhariam por falta de dado nosso, que é o oposto do que se quer observar. Rodar o roteiro completo a cada tentativa sujaria o sandbox com dezenas de boletos por nada.

Vale a mesma janela de sempre — seg-sex, 7h-23h BRT. Fora dela todo caso falha na autenticação, e uma rodada inteira em vermelho por horário não diz nada sobre o que se está observando.

Compare com o estado de 04/08 na tabela acima: 502 em P_03_01, P_03_03 e P_03_04, 403 em C_05_02, e massa ausente em P_05_01, P_05_03 e P_05_04. Qualquer um desses virando 2xx é a notícia.

Quando algo destravar: rode o roteiro completo, regenere o .docx e atualize os números da seção acima — eles são daquela rodada e não se atualizam sozinhos.

Isto não é agendado, e é de propósito. Um cron de Actions só dispara a partir do branch default, e homologação não sobe para a main. Um schedule: num branch de HML não executa nunca — e uma sonda que promete cadência sem entregar é pior do que nenhuma: daqui a uma semana alguém conclui “nada mudou no sandbox” a partir de zero execução.

O que reportar ao C6

Três coisas dependem do banco, e nenhuma tem contorno do nosso lado:

  1. /v2/pix/lotecobv responde 502 em PUT e em GET, enquanto /cob, /cobv e /pix respondem 200 na mesma conexão. A spec do C6 nem documenta 502.
  2. A página de pagamento do checkout não abre — payment-h.c6pay.com.br devolve 403 do Cloudflare. Sem ela não há como pagar um link, e C_05_02 fica sem gatilho possível.
  3. Os identificadores repetidos no formulário v3.0, na tabela acima.

E uma pergunta: como injetar um Pix recebido na conta sandbox? Sem isso P_05_01/03/04 não têm e2eid para exercitar, e a API de Agendamento de Pagamentos não resolve — ela não executa pagamento, só enfileira para aprovação manual no internet banking.

Depois da aprovação

Conta PJ no mesmo CNPJ inscrito no Portal do Desenvolvedor. MEI não é elegível.