TF Fiscal
Documentación

NFS-e

Emita facturas de servicios (NFS-e) en nombre de un emisor registrado: flujo de integración, diferencias entre canales municipales, manifestación de facturas recibidas, cargas de los webhooks, modelo de errores, máquina de estados y checklist de integración.

Visión general y flujo de integración

PasoEndpointNotas
1 Registrar emisorPOST /openapi/v2/empresasIgual que NF-e, con la nueva sección opcional emissaoNFSe; el bloque de NF-e puede omitirse si solo emite NFS-e, y entonces no se exige la IE
2 Vincular certificadoPOST /openapi/v1/empresas/{empresaId}/certificadoDigitalIgual que NF-e
3 Registrar callbackPOST /openapi/v1/webhooksIgual que NF-e; los resultados de NFS-e reutilizan la misma URL de callback
4 EmitirPOST /openapi/v2/empresas/{empresaId}/nfseDevuelve HTTP 200 sin cuerpo al aceptar; el envío es asíncrono
5 ConsultarGET /openapi/v2/empresas/{empresaId}/nfse/{nfseId}Estado, eventos, enlaces de descarga del XML / DANFSe, eco de la solicitud
5-A ConciliarGET …/nfse/emitidas · GET …/nfse/emitidas/{chaveAcesso}Listado de emitidas (paginación por ventana de tiempo) y consulta por clave de acceso
6 CancelarPOST /openapi/v2/empresas/{empresaId}/nfse/{nfseId}/cancelarAsíncrono: 200 con acuse de aceptación, resultado vía webhook
7 Consultar facturas recibidasGET …/nfse/recebidas · GET …/nfse/recebidas/{chaveAcesso}Lista de las facturas recibidas (paginada por período) y consulta de una por la clave; de aquí sale la chaveAcesso usada en la manifestación
8 Manifestar sobre factura recibidaPOST …/recebidas/{chaveAcesso}/manifestarRegistra confirmación / rechazo de una NFS-e recibida; el cuerpo trae tipo

La autenticación es idéntica a la de NF-e: cabeceras token / timestamp / sign, vea Autenticación.

Tres diferencias estructurales frente a NF-e

1. La clave de acceso tiene 50 dígitos y la genera el emisor oficial. La clave de 44 dígitos de la NF-e la calcula el contribuyente; la clave de la NFS-e solo existe cuando la autoridad acepta el documento. Un documento fallido, por tanto, no tiene chaveAcesso y solo puede localizarse por identificacaoDps, el identificador de DPS de 45 caracteres que generamos.

2. La factura de servicios la rige el municipio. La plataforma enruta por el municipio del emisor; el canal resultante aparece como padraoMunicipal en la respuesta de la consulta. Hoy se admiten el estándar nacional (Nacional) y el sistema municipal de São Paulo (Paulistana); un municipio no admitido se rechaza en la aceptación (10018010) en vez de aceptarse y fallar de forma asíncrona.

3. La cancelación tiene ventana, y fuera de ella la respuesta no es "no se puede cancelar" sino "pasa a análisis municipal". Vea Cancelar NFS-e.

Requisitos previos

  • El emisor debe estar aprobado y con certificado utilizable, de lo contrario la aceptación se rechaza (10018004).
  • El emisor debe tener perfil de NFS-e, creado con la sección emissaoNFSe de Registrar empresa o mantenido por operaciones en la consola. El encuadre en el Simples, el cálculo en el Simples, el régimen especial y la serie del DPS vienen siempre del perfil; la solicitud de emisión no los envía ni los sustituye. Sin perfil, la aceptación rechaza (10018005). Código de servicio, CNAE, NBS y los demás campos del servicio no están en el perfil: van en cada nota.
  • El ambienteEmissao debe coincidir con el entorno actual del emisor. Tras el registro el emisor queda en el entorno de pruebas (Homologacao); el paso a producción es una acción de operaciones y no se expone por la API.
  • Los valores de tributación siguen la solicitud: lo que trae prevalece, y solo lo que falta lo busca la plataforma en los datos de referencia fiscal, como la lista de la LC 116, la clasificación y las alícuotas de retención federal y la carga aproximada del IBPT. Si los datos que necesitan la retención federal, las alícuotas propias de PIS/COFINS o el lugar de incidencia del ISS aún no se importaron, la aceptación rechaza con 10018065, listando los campos de la solicitud que pueden sustituirlos.
  • Cuando el receptor es persona jurídica (CNPJ) hay retención federal: envíe los importes en servico.retencoes, donde cero declara que no hay retención, u omítalos junto con pisCofins.tipoRetencao y la plataforma los determina por la clasificación oficial de retención del servicio y por cliente.orgaoPublico y cliente.optanteSimplesNacional; enviar pisCofins.tipoRetencao sin los importes se rechaza (10018001). La información faltante se rechaza explícitamente (10018023) con todo lo que falta listado de una vez, en lugar de tratarse como cero.

Restricciones adicionales del canal Paulistana

Un emisor de São Paulo (padraoMunicipal = Paulistana) necesita su CCM (inscricaoMunicipal): si está en el perfil, se usa tal cual; si falta, la plataforma consulta el sistema municipal por CNPJ en la aceptación y guarda el resultado en el perfil; la aceptación solo se rechaza (10018005) cuando no se encuentra nada.

El canal no admite campos de descuento: incorpore el descuento al importe del servicio o a la deducción. Tampoco admite emisión sustitutiva (el layout municipal de RPS no tiene ese grupo): cancele la original y emita una nueva; enviar el grupo se rechaza en la aceptación (10018001).

También obtiene dos capacidades automáticas que no requieren ningún endpoint nuevo: las facturas paulistanas recibidas se traen directamente del sistema municipal al listado de recibidas (origem=PrefeituraSP, fusionadas automáticamente cuando llega la transcripción de la ADN); una factura emitida y cancelada en el portal municipal se sincroniza a Cancelada y el nfse.canceled se envía con normalidad.

Máquina de estados

text
┌──────────────► Negada (terminal)
│
Pendente ────────┼──────────────► Autorizada ──┬──► Cancelada (terminal)
│ │
└──────────────► Falha ├──► EmProcessoDeCancelamento ──┬──► Cancelada
(falló antes de la │ └──► Autorizada (análisis denegado)
numeración, sin documento) └──► Substituida (sustituida)
EstadoSignificadoTerminal
PendenteAceptado, aún sin desenlaceno
AutorizadaEmitida con éxitono (puede cancelarse o sustituirse)
NegadaRechazada por la autoridadsí
FalhaFallo del lado de la plataforma (parámetros inválidos / emisor no apto); no se creó ningún documentosí
CanceladaCanceladasí
EmProcessoDeCancelamentoAnálisis de cancelación aceptado, a la espera del municipiono
SubstituidaSustituida por otro documentosí

Estado de manifestación de una factura recibida

El status de una factura recibida usa Autorizada / Cancelada / Substituida de la tabla anterior; la manifestación de este emisor se guarda aparte en el bloque manifestacao, y cada parte manifiesta como máximo una vez por factura.

text
(sin manifestación, filtro de la lista Pendente) ──┬──► Confirmada (confirmada por este emisor, terminal)
├──► Rejeitada (rechazada por este emisor) ──► RejeicaoAnulada (rechazo anulado por el municipio, terminal)
└──► ConfirmacaoTacita (confirmación tácita del municipio, terminal)
EstadoSignificado¿Puede manifestar aún?
null (valor de filtro Pendente)Sin manifestaciónsí (mientras la factura esté Autorizada)
ConfirmadaConfirmada por este emisorno
RejeitadaRechazada por este emisorno
ConfirmacaoTacitaConfirmada tácitamente por el municipio tras el plazono
RejeicaoAnuladaEl municipio anuló el rechazo de este emisorno

Callbacks de webhook

Se entregan en la URL que usted registra como carga JSON pura.

Código del eventoDisparonfseStatus
nfse.authorizedEmitida con éxitoAutorizada
nfse.rejectedRechazada por la autoridad o fallo de nuestro ladoNegada
nfse.canceledCancelación completada (incluido análisis aprobado)Cancelada
nfse.cancel_requestedAnálisis de cancelación aceptadoEmProcessoDeCancelamento
nfse.cancel_deniedLa cancelación no ocurrió y el documento sigue autorizado: rechazo síncrono de la autoridad, envío agotado, o solicitud de análisis denegada por el municipioAutorizada
nfse.substitutedEste documento fue sustituido; la carga trae un nfseChaveSubstituta adicionalSubstituida
nfse.inbound.receivedNFS-e recibida (este emisor es receptor / intermediario, requiere suscripción explícita)—
nfse.inbound.canceledNFS-e recibida cancelada (requiere suscripción explícita)—
nfse.inbound.substitutedNFS-e recibida sustituida (requiere suscripción explícita)—

Aviso: Semántica de las suscripciones. Una aplicación que nunca registró ninguna fila de suscripción recibe los seis eventos de salida. En cuanto exista cualquier fila de suscripción para la aplicación (por ejemplo un evento de entrada), pasa al modo lista de permitidos y solo se entregan los eventos habilitados explícitamente. Al suscribirse a eventos de entrada, habilite también los eventos de salida que necesite, o las notificaciones de salida quedarán en espera de destinatario.

json
{
"tipo": "NFS-e",
"empresaId": "1001",
"nfseId": "PED-20260918-001",
"nfseStatus": "Autorizada",
"nfseMotivoStatus": null,
"nfseLinkDanfse": "https://api.v2.tffiscal.com/openapi/files/danfse/…",
"nfseLinkXml": "https://api.v2.tffiscal.com/openapi/files/xml/9001?token=…",
"nfseNumero": "1287",
"nfseSerie": "1",
"nfseChaveAcesso": "3550308…",
"nfseIdentificacaoDps": "DPS3550308…",
"nfseDataEmissao": "2026-09-18T13:00:00Z",
"nfseDataAutorizacao": "2026-09-18T13:00:03Z",
"nfseNumeroProtocolo": null,
"nfseAtualizadoEm": "2026-09-18T13:00:03Z"
}

nfseAtualizadoEm es el momento de este cambio de estado. El orden de entrega no está garantizado: los reintentos y las múltiples instancias pueden hacer que un evento antiguo llegue después de uno nuevo. Compárelo con la marca de tiempo que ya tiene y descarte el más antiguo en vez de sobrescribir el estado por orden de llegada.

En un callback de fallo el nfseChaveAcesso puede venir vacío (la autoridad nunca generó la clave); concilie por nfseIdentificacaoDps en ese caso. Un callback de fallo anterior a la numeración no trae ninguno de los dos, y solo el nfseId concilia.

Modelo de errores

Los endpoints públicos devuelven un array puro:

json
[{"codigo": "10018012", "mensagem": "Codigo de servico fora da lista oficial LC 116: 999999"}]
CódigoSignificadoQué hacer
10018001Validación de parámetros rechazada en la aceptación (el mensaje indica el motivo)Corrija según el mensaje
NFSe0001Documento no encontrado: el nfseId no pertenece a este emisor, o la clave de entrada no está entre sus facturas recibidasCoteje nfseId / chaveAcesso con empresaId
10018004Emisor no apto (desactivado / certificado inutilizable)Revise el estado del emisor y el certificado
10018005Emisor sin perfil de NFS-eCréelo antes en Registrar empresa con la sección emissaoNFSe
10018010El estándar de NFS-e del municipio aún no está admitidoEse municipio todavía no puede emitir, contacte con la plataforma
10018012Código de servicio fuera de la lista LC 116Coteje codigoTributacaoNacional
10018013Documento del receptor inválidoCoteje el CPF / CNPJ / NIF
10018014Exportación de servicio sin país de destinoInforme servico.paisPrestacao
10018015El documento sustituido no puede sustituirseRevise el estado del documento sustituido
10018020No se puede determinar la alícuota de ISSEnvíe servico.iss.aliquota o el servico.codigoTributacaoMunicipal correcto
10018022Un emisor del Simples no puede enviar la alícuota de ISS directamenteQuite aliquota
10018023La retención federal no puede determinarse; el mensaje lista todo lo que faltaInforme los campos listados o envíe los importes retenidos en servico.retencoes
10018030La misma solicitud ya se está procesandoReintente más tarde
10018031Ese pedido ya tiene factura, o el mismo id trae contenido distintoUse otro número de pedido o coteje el contenido
10018040Ya hay un análisis de cancelación en cursoEspere el veredicto
10018041El documento ya fue sustituidoNo se permite ninguna otra operación
10018042El estado actual no permite este eventoRevise el estado del documento
10018063El mensaje del DPS no cumple el XSD oficial (el detalle trae línea, columna, clave del error y nombre del elemento)Corrija según el detalle: suele ser texto fuera de Latin-1, dirección incompleta, o un valor fuera de la tabla oficial
10018064El mensaje de evento de la NFS-e no cumple el XSD oficialRevise la longitud de motivo (15-255), el valor de codigoMotivo y el juego de caracteres
10018065Los datos de referencia fiscal de la NFS-e que necesita esta nota no se han importado, rechazo en la aceptación; el mensaje lista cada elemento con una flecha hacia el campo de la solicitud que lo sustituyeEnvíe en la solicitud los campos tras la flecha, o confirme con la plataforma que los datos están importados; para iss-local-incidencia, basta con enviar servico.iss.municipioIncidencia

Los errores de autenticación y autorización (10009xxx) están en Autenticación; la tabla completa está en Códigos de error.

Checklist de integración

  1. Registre el emisor (con emissaoNFSe) → vincule el certificado → registre el webhook.
  2. Emita una factura mínima en Homologacao (solo los campos obligatorios), confirme que llega el nfse.authorized y que el XML y el DANFSe se descargan.
  3. Envíe el mismo id otra vez y confirme que no se emite una segunda factura.
  4. Envíe un código de servicio inexistente y confirme el rechazo síncrono 10018012, y no una Negada asíncrona.
  5. Cancele una factura autorizada y confirme que llega a Cancelada o EmProcessoDeCancelamento según la ventana.
  6. Consulte un documento fallido y confirme que concilia por identificacaoDps, no por chaveAcesso.
  7. Manifieste sobre una factura recibida con tipo=Confirmacao y vea que el detalle trae manifestacao.status=Confirmada; envíe tipo=Rejeicao en la misma factura y confirme el 10018042 (cada parte manifiesta una vez).