NFS-e de São Paulo: Manual 3.4 (adequação à NT 009)
A Prefeitura de São Paulo publicou em outubro de 2026 o Manual do Web Service 3.4 e o XSD schemas-reformatributaria-v02-7. Eles adequam o leiaute 2 da NFS-e Paulistana (a nota com IBS e CBS, quando você informa ibsCbs.classCode) à NT SE/CGNFS-e 009.
Nada é obrigatório. O payload que você envia hoje continua válido. A única mudança com data marcada é automática: a partir do fato gerador de 01/12/2026, a NFE.io envia os documentos de reembolso no grupo novo da prefeitura.
Resumo
| Mudança | Quando | O que você faz |
|---|---|---|
Documentos de reembolso passam de gReeRepRes para vAjusteBC | Fato gerador a partir de 01/12/2026 | Nada. A NFE.io faz a troca pela data |
baseCalculationAdjustmentType nos documentos de reembolso | Aceito a partir de 01/12/2026 | Opcional. Antes dessa data, a nota é recusada com [E1006] |
Campo novo ibsCbs.creditReversal (estorno de crédito na doação) | Quando a NFE.io habilitar os grupos da NT 009 em São Paulo | Envie só quando precisar. Hoje a nota com o campo é recusada |
| Grupos opcionais: doação, país do resultado, pagamentos vinculados, comércio exterior | Quando a NFE.io habilitar os grupos em São Paulo | Nada até lá. Os campos são ignorados, como hoje |
O ambiente de teste da Prefeitura de São Paulo ainda valida o RPS pelo XSD anterior (v02-6), que não aceita os grupos novos. Por isso, os grupos opcionais e o comércio exterior estão desligados em produção. A NFE.io vai habilitá-los quando a prefeitura passar a aceitar o XSD v02-7, e vai comunicar a data nas Release Notes. Se a prefeitura adiar o início do vAjusteBC, a NFE.io acompanha a nova data. Você não precisa mudar o payload em nenhum dos casos.
Documentos de reembolso a partir de 01/12/2026
O Manual 3.4 proíbe enviar gReeRepRes e vAjusteBC na mesma nota. A partir de 01/12/2026, a prefeitura desconsidera o gReeRepRes: a base de cálculo ficaria com o reembolso dentro. Por isso, a NFE.io escolhe o grupo só pela data do fato gerador:
- Fato gerador até 30/11/2026: os documentos saem em
gReeRepRes, como hoje. - Fato gerador a partir de 01/12/2026: os documentos saem em
vAjusteBC/docAjusteBC.
O fato gerador é a data do RPS: a competência (accrualOn) e, sem ela, a data de emissão.
Cada documento leva no docAjusteBC:
| Tag | Origem na API |
|---|---|
dFeNacional, docFiscalOutro ou docOutro | otherNationalDfe, otherFiscalDoc ou otherDoc |
fornec | supplier |
dtEmiDoc | issueDate |
dtCompDoc | accrualOn do documento e, sem ela, issueDate |
tpAjusteBC | baseCalculationAdjustmentType, se informado. Sem ele, o código derivado do reimbursementType: 101 a 104, ou 199 para OtherReimbursement |
xTpAjusteBC | reimbursementTypeText, só nos tipos 99 e 199, com no máximo 150 caracteres |
vTotDoc e vAjusteAplic | amount |
As deduções do ISSQN continuam em deductionsAmount (ValorDeducoes). Os documentos de dedução (deduction.documents) não entram no RPS de São Paulo, com ou sem baseCalculationAdjustmentType.
Documento de reembolso incompleto ([E1004])
A regra do Manual 3.3.9 continua e passa a seguir o grupo em que o documento sai:
gReeRepRes(até 30/11/2026):reimbursementTypeválido. O tipoOtherReimbursementexigereimbursementTypeText.vAjusteBC(a partir de 01/12/2026): os tipos de ajuste 99 e 199 exigemreimbursementTypeText.
Nos dois períodos, o documento precisa de identificação, issueDate e amount maior que zero. Veja os exemplos em Emissão de NFS-e em São Paulo: Valor Total Recebido e documentos de reembolso.
Grupos opcionais da NT 009
Quando a NFE.io habilitar os grupos em São Paulo, eles saem só quando a nota traz o dado:
| Grupo | Origem na API | Quando sai |
|---|---|---|
indDoacao | ibsCbs.isDonation | isDonation = true |
cPaisResult | borrower.address.country | Exportação (classCode 410004) com location no Brasil. Sem location, o RPS leva cPaisPrestacao e o cPaisResult não sai |
gPgtoVinc | ibsCbs.paymentLinks | Quando a lista é informada |
gEstornoCred | ibsCbs.creditReversal | Quando os dois valores são informados |
comExt | foreignTrade | Exportação ou tomador estrangeiro. O foreignTradeBaseCalculationAdjustment vai no comExt só na exportação |
Campo novo: ibsCbs.creditReversal
Estorno de créditos de IBS e CBS na doação sem contraprestação (gIBSCBS/gEstornoCred).
"ibsCbs": {
"classCode": "410026",
"operationIndicator": "100301",
"isDonation": true,
"creditReversal": { "ibsAmount": 1.50, "cbsAmount": 8.80 }
}
ibsAmount(vIBSEstCred) ecbsAmount(vCBSEstCred): os dois são obrigatórios no grupo.- Um objeto vazio ou com os dois valores zerados vale como ausente.
- Só São Paulo emite este grupo. Nas demais cidades, e nas notas emitidas pelo Ambiente Nacional, a nota com
creditReversalé recusada antes do envio.
Diferenças em relação ao leiaute nacional
O XSD de São Paulo tem regras próprias em alguns campos. A NFE.io formata o que pode; o resto vai como você enviou, e a prefeitura valida:
| Campo | Leiaute nacional | São Paulo |
|---|---|---|
paymentLinks[].number (nPag) | número | 3 dígitos (001). A NFE.io completa com zeros |
paymentLinks[].paymentInstitutionBaseTaxNumber (CNPJBasePSP) | CNPJ completo | Raiz de 8 posições. A NFE.io extrai a raiz de um CNPJ válido |
paymentLinks[].transactionId (idTransacao) | 2 a 35 caracteres sem espaço | 2 a 35 letras maiúsculas ou dígitos |
foreignTrade.currency (tpMoeda) | ISO 4217 | Tabela de moedas do Banco Central (USD = 220, EUR = 978, GBP = 540, JPY = 470, BRL = 790). Informe a sigla ou o código de 3 dígitos |
foreignTrade.invoiceNumber e exchangeContractNumber | até 20 caracteres | 20 dígitos. A NFE.io completa com zeros um número só de dígitos |
Recusas antes do envio ([E1006])
A NFE.io recusa antes do envio só o que o RPS deixaria de fora ou trocaria em silêncio. O que o RPS leva vai como você enviou, e a prefeitura valida pelo XSD e pelas regras dela. Quando a NFE.io recusa, a nota termina como falha de emissão, o webhook é disparado e nada é enviado à prefeitura.
| Campo | Motivo da recusa | Ação |
|---|---|---|
ibsCbs.classCode | Informado em branco | Retire o campo (leiaute 1) ou informe o código de 6 dígitos |
ibsCbs.adjustmentPurpose | A NFS-e de ajuste não existe no leiaute de São Paulo | Retire o campo |
ibsCbs.thirdPartyReimbursements.documents[].baseCalculationAdjustmentType | Fato gerador antes de 01/12/2026, ou nota sem classCode (leiaute 1) | Retire o campo e use reimbursementType |
ibsCbs.creditReversal | Grupos da NT 009 ainda não habilitados em São Paulo; nota sem classCode; só um dos dois valores | Retire o campo ou informe os dois valores |
foreignTrade.concurrentConsumption | O comExt não está habilitado em São Paulo ou não sairia nesta nota | Retire o campo |
ibsCbs.foreignTradeBaseCalculationAdjustment | Com o comExt habilitado: nota que não é exportação ou sem foreignTrade | Retire o campo ou informe foreignTrade |
foreignTrade.currency | Com o comExt emitido: sigla sem código na tabela do Banco Central | Informe o código de 3 dígitos ou retire o campo (vale BRL) |
borrower.address.country | Com o comExt habilitado, fora da exportação: país que não é o Brasil nem está na tabela de países (ISO 3166-1 alfa-3) | Corrija o país do tomador |
As recusas [E1003] (valor recebido sem cobertura) e [E1004] (documento de reembolso incompleto) continuam. O [E1004] segue a regra por período descrita em Documento de reembolso incompleto.
Homologação
O fluxo atual (inclusive os reembolsos em gReeRepRes) pode ser testado hoje no ambiente de teste da Prefeitura de São Paulo. Fale com o suporte da NFE.io, que orienta a configuração da Inscrição Municipal de testes.
Os grupos novos (vAjusteBC, doação, país do resultado, pagamentos vinculados, estorno de crédito e comércio exterior) só poderão ser testados quando o ambiente de teste da prefeitura aceitar o XSD v02-7. Em 04/11/2026, ele ainda valida pelo XSD anterior e recusa esses grupos. A NFE.io avisa nas Release Notes quando o teste estiver disponível.