Skip to content

v0.2.0: o contrato oficial v1.1.0, com assinatura

Latest

Choose a tag to compare

@Mozurok Mozurok released this 04 Sep 19:03
b176e9e

@splitbr/client e @splitbr/mock passam a ser gerados do OpenAPI v1.1.0, publicado pelo CGIBS em 24/08/2026. Quebra compatibilidade com a linha 0.1.x.

👉 Guia de migração, campo a campo.

Os quatro headers obrigatórios não existem mais

messageId, correlationId, tenantId e timestamp sumiram de components.parameters, e o Manual de Integração v1.1.0 não os cita uma única vez. No lugar entrou um só: X-JWS-Signature, obrigatório nas 43 operações.

A assinatura, e por que o client não aceita ela pronta

O contrato pede JWS Compact Detached (RFC 7515) sobre o corpo canonicalizado em JCS (RFC 8785), RS256, com sete atributos no protected header.

O b64: false (RFC 7797) é o detalhe que decide o desenho: a assinatura cobre os bytes crus do payload, então quem assina precisa ver exatamente o que vai na rede. Se a assinatura viesse montada de fora, o chamador serializaria o corpo por conta própria, e duas serializações do mesmo objeto divergem em ordem de chave, formato de número ou escaping. O resultado seria uma assinatura válida sobre bytes que ninguém enviou, rejeitada sem pista de por quê.

Então o client canonicaliza, monta o protected header, calcula a entrada e remonta o detached. A operação RS256 sai por um callback seu:

createSplitClient({
  baseUrl,
  kid: "minha-chave-01",
  assinar: (bytes) => hsm.signRS256(bytes),   // a chave privada nunca entra no pacote
})

Existe uma serialização só, e é a que vai na requisição.

O resto do delta

v0.0.10 v1.1.0
rotas 32 35
schemas 57 78
stream {idPsp}/tributos {cnpjRaizPspRecDir}/transacoes
Mecanismo de Ocorrências — 3 rotas

Campos renomeados: cnpjCpfPagOrig → cnpjPagOrig (que passou a aceitar só CNPJ; pagador pessoa física saiu do contrato), valorTotalCbs/Ibs → vlTotalCbs/Ibs, fromNsu/toNsu → nsuInicial/nsuFinal, tributos → transacoes.

Tipos: numIdentcBaixa e nsuId viraram string. Cuidado com nsuId: comparar NSU com > passou a ordenar lexicograficamente, e "9" > "10" é verdadeiro.

Formatos fixos: numCodBarras com 44 dígitos; idLote = idInfSegr + sequencial (40 posições), o que amarra o lote ao informe no próprio identificador.

Removido: PATCH /api/v1/pix-automatico (o Informe de Transação Atualizada perdeu o Pix Automático).

No mock

As três rotas do MOC estão implementadas, com resposta simulada determinística da RFB/CGIBS, para o ciclo fechar sem a plataforma real.

A assinatura é conferida na forma, sem ser exigida: verificar de verdade obrigaria quem roda npx splitbr-mock a gerar par de chaves antes da primeira resposta, e o valor do mock é não precisar de setup. Conferir a forma pega o erro provável em produção, que é um JWS bem-formado com b64 errado ou com o payload anexado em vez de detached. Para o modo fiel: buildServer({ exigirAssinatura: true }).

Os quatro headers antigos continuam aceitos, e o correlationId segue ecoado por utilidade de depuração, mas nenhum é obrigatório.

Compatibilidade

^0.1.1 não puxa a 0.2.0 sozinho: em 0.x o caret do npm não atravessa o minor. A atualização é deliberada.

Ficou em 0.2.0 e não em 1.0.0 de propósito: pré-1.0 sinaliza quebra no minor, e afirmar estabilidade de API seria falso enquanto três manuais da família não foram publicados, dois seguem em minuta, e o Manual de Segurança (que descreve o JWKS por trás da assinatura) não existe.

Verificação

testes      227  (71 client + 115 mock + 41 detector)   antes: 162
typecheck   0 erros, Node 22 e 24
drift       4/4 MATCH

Full Changelog: v0.1.1...v0.2.0