POST Atualizado 09/2020


Vou fazer um artigo no qual recebo várias perguntas: Como gerar arquivos XML no padrão TISS da ANS.  Vou demonstrar usando PHP e API DOM nesta primeira parte e futuramente complementarei com dados a partir de banco de dados MySQL.

O padrão TISS é determinado pela ANS, você poderá consultar outras informações do padrão TISS no site da Agência Nacional de Saúde.

Para seguir, é necessário ter noções básicas da linguagem PHP.

Obs.: Não vou ensinar como desenvolver um sistema com a finalidade de faturamento, apenas o passo a passo da geração do XML no padrão TISS usando o PHP e a biblioteca DOM.

Basicamente o faturamento dos atendimentos/contas, consiste no atendimento do beneficiário pelo prestador(clínica, hospital, laboratório, banco de sangue, clínicas de imagem, entre outros), que é credenciado as operadoras de saúde (Bradesco Saúde, Unimed, Postal Saúde, Geap, Cassi, Capesp, Saúde Itaú, Sul América,…).

O envio do faturamento é feito por lotes(vários atendimentos no mesmo lote, geralmente até 100 atendimentos no mesmo lote) e pode ser via portal da Operadora por digitação das contas (quando a mesma oferece o recurso) ou a partir do envio de arquivos XML. E cada operadora permite e aceita o envio até uma data limite de cada mês(competência), por exemplo; a operadora XYZ aceita que o envio seja feito até o dia 20, e fará o pagamento até o dia 19 do mês subsequente(30 dias após o envio). Desta forma os prestadores precisam ficar atentos ao cumprimento de envio nas datas certas para receber no prazo, caso contrário o pagamento pela operadora é feito na próxima competência.

A geração do XML consiste em dados dos pilares: Operadora de Saúde <-> Prestador de Serviços <-> Beneficiários/Segurados,  ou seja, precisamos das informações de credenciamento do prestador de saúde,  dados do prestador e do segurado. Abaixo uma exemplificação dos dados;

Dados da operadora:
Registro ANS: 1111
Versão TISS: 03.03.03

Dados do Prestador:
Código de Credenciamento: 12345
CNPJ: 00.000.000/0000-0 (Fictício)

Dados de faturamento:
Número da remessa/fatura/Lote: 123

Dados do atendimento:
Data e Hora: 03/04/2018 22:15:00
Nome: Fulano de Tal
Carteira: 4444444444444444
Validade da carteira: 31/12/2030
Recém nascido: Não
Tipo de Atendimento: Ambulatorial
Caráter do atendimento: Eletivo
Guia/Senha: 1111/2222

Médico: Dr. Fabiano
CRM: 0000
CBOS:

Código da tabela: 22
Procedimento TUSS: 10101012
Descrição do Procedimento: Consulta em consultório
Valor unitário: 500,00
Valor Total:  500,00

<?php
#Definindo as variáveis

#Dados Operadora:
$_XML['versao_tiss']='030303';
$_XML['registro_ans'] = '1111';

#Dados Prestador:
$_XML['codigo_credenciamento'] = '12345';
$_XML['cnpj'] = '0000000000000';
$_XML['prestador'] = 'Hospital ABCD';

#Dados do atendimento e beneficiário
$_XML['data_hora'] = '03/04/2018 22:15:00';
$_XML['rn'] = 'N'; #Não 
$_XML['tipo_atd'] = 'Ambulatorial'; 
$_XML['carater'] = 'E'; #Eletivo 
$_XML['guia'] = '1111'; 
$_XML['senha'] = '2222'; 
$_XML['medico'] = 'Dr. Fabiano'; 
$_XML['crm'] = '0000'; 
$_XML['cbos'] = '';
#Dados do beneficiário
$_XML['nome'] = 'Fulano de Tal';
$_XML['dt_nascimento'] = '01/01/1980';
$_XML['carteira']  = '4444444444444444';
$_XML['validade'] = '31/12/2030';

#Dados da Fatura / Lote
$_XML['fatura_remessa'] = '123';

#Dados do procedimento realizado
$_XML['tabela'] = '22';
$_XML['procedimento_tuss'] = '10101012';
$_XML['descricao_proced'] = 'Consulta em consultório';
$_XML['valor_unitario'] = '500,00';
$_XML['qtde'] = '1';
$_XML['valor_total'] = '500,00';

$_XML['tipoTransacao'] = 'ENVIO_LOTE_GUIAS';
$_XML['sequencialTransacao'] = '6658';
$_XML['dataRegistroTransacao'] = '2018-01-18';
$_XML['horaRegistroTransacao'] = '10:00:00';

 # Utilize a variável $_XML['hash_dados'] para concatenar os dados e calcular o HASH antes do terceiro bloco
$_XML['hash_dados'] = '';

#A variável $_XML['hash'] está nula pois deve ser calculada com os dados dos elementos(tags) do XML
$_XML['hash'] = 'calculo do HASH';

//$_XML[''] = ''; // para criar novas variáveis apenas siga o padrão

Após a declaração das variáveis, vamos iniciar a geração da estrutura no nosso arquivo.

#versao XML e codificação
$xml = new DOMDocument("1.0", "ISO-8859-1"); 
//também poderia ser UTF-8
 
#remove os espacos em branco
$xml->preserveWhiteSpace = false;

#Realizar a quebra dos blocos do XML por linha
$xml->formatOutput = true;

		//Criação dos elementos do Namespace ans:mensagemTISS
		$xml->createAttributeNS( 'http://www.w3.org/2000/09/xmldsig#', 'ds:attr' );
		$xml->createAttributeNS( 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:attr' );
		$xml->createAttributeNS( 'http://www.ans.gov.br/padroes/tiss/schemas http://www.ans.gov.br/padroes/tiss/schemas/tissV3_03_01.xsd', 'schemaLocation:attr' );
		$xml->createAttributeNS( 'http://www.ans.gov.br/padroes/tiss/schemas', 'ans:attr' );
        
        
// Nó / Bloco Principal
// ans:mensagemTISS
$mensagemTISS = $xml->createElement("ans:mensagemTISS");
$xml->appendChild($mensagemTISS);

	/* primeiro bloco */
	// ans:mensagemTISS / ans:cabecalho
	$cabecalho = $xml->createElement("ans:cabecalho");
	$mensagemTISS->appendChild($cabecalho);
	
	
		// ans:mensagemTISS / ans:cabecalho / ans:identificacaoTransacao
		$identificacaoTransacao = $xml->createElement("ans:identificacaoTransacao");
		$cabecalho->appendChild($identificacaoTransacao);
		
				# ans:tipoTransacao
				$tipoTransacao = $xml->createElement("ans:tipoTransacao", $_XML['tipoTransacao']);
				$identificacaoTransacao->appendChild($tipoTransacao);
				
				#sequencialTransacao
				$sequencialTransacao = $xml->createElement("ans:sequencialTransacao", $_XML['sequencialTransacao']);
				$identificacaoTransacao->appendChild($sequencialTransacao);

				#dataRegistroTransacao
				$dataRegistroTransacao = $xml->createElement("ans:dataRegistroTransacao", $_XML['dataRegistroTransacao']);
				$identificacaoTransacao->appendChild($dataRegistroTransacao);

				#horaRegistroTransacao
				$horaRegistroTransacao = $xml->createElement("ans:horaRegistroTransacao", $_XML['horaRegistroTransacao']);
				$identificacaoTransacao->appendChild($horaRegistroTransacao);
			
		
		// ans:mensagemTISS / ans:cabecalho / ans:origem
		$origem = $xml->createElement("ans:origem");
		$cabecalho->appendChild($origem);
		
				// ans:mensagemTISS / ans:cabecalho / ans:origem / identificacaoPrestador
				$identificacaoPrestador = $xml->createElement("ans:identificacaoPrestador", $_XML['cnpj']);
				$origem->appendChild($identificacaoPrestador);
				
		
		// ans:mensagemTISS / ans:cabecalho / ans:destino
		$destino = $xml->createElement("ans:destino");
		$cabecalho->appendChild($destino);
		
				// ans:mensagemTISS / ans:cabecalho / ans:registroANS
				$registroANS = $xml->createElement("ans:registroANS", $_XML['registro_ans']);
				$destino->appendChild($registroANS);
		
		// ans:mensagemTISS / ans:cabecalho / ans:Padrao
		$Padrao = $xml->createElement("ans:Padrao", $_XML['padrao_tiss']);
		$cabecalho->appendChild($Padrao);
	
	
	/* segundo bloco */
	// ans:mensagemTISS / ans:prestadorParaOperadora
	$prestadorParaOperadora = $xml->createElement("ans:prestadorParaOperadora");
	$mensagemTISS->appendChild($prestadorParaOperadora);
	
		// ans:mensagemTISS / ans:prestadorParaOperadora / loteGuias
		$loteGuias = $xml->createElement("ans:loteGuias");
		$prestadorParaOperadora->appendChild($loteGuias);		

			// ans:mensagemTISS / ans:prestadorParaOperadora / loteGuias / numeroLote
			$numeroLote = $xml->createElement("ans:numeroLote", $_XML['lote_remessa']);
			$loteGuias->appendChild($numeroLote);	
 
 			// ans:mensagemTISS / ans:prestadorParaOperadora / loteGuias / guiasTISS
			$guiasTISS = $xml->createElement("ans:guiasTISS");
			$loteGuias->appendChild($guiasTISS);	

// ans:mensagemTISS / ans:prestadorParaOperadora / loteGuias / guiaConsulta
$guiaConsulta = $xml->createElement("ans:guiaConsulta");
$loteGuias->appendChild($guiaConsulta);

// ans:mensagemTISS / ans:prestadorParaOperadora / loteGuias / cabecalhoConsulta
$cabecalhoConsulta = $xml->createElement("ans:cabecalhoConsulta");
$guiaConsulta->appendChild($cabecalhoConsulta);

$registroANS = $xml->createElement("ans:registroANS", '132'); //registroANS
$cabecalhoConsulta->appendChild($registroANS);

$registroANS = $xml->createElement("ans:numeroGuiaPrestador", '1111'); //numeroGuiaPrestador
$cabecalhoConsulta->appendChild($registroANS);

$numeroGuiaOperadora = $xml->createElement("ans:numeroGuiaOperadora", '2222'); //numeroGuiaOperadora
$guiaConsulta->appendChild($numeroGuiaOperadora);

$dadosBeneficiario = $xml->createElement("ans:dadosBeneficiario"); //dadosBeneficiario
$guiaConsulta->appendChild($dadosBeneficiario);

$numeroCarteira = $xml->createElement("ans:numeroCarteira", '1122334455'); //numeroCarteira
$dadosBeneficiario->appendChild($numeroCarteira);

$atendimentoRN = $xml->createElement("ans:atendimentoRN", 'N'); //atendimentoRN
$dadosBeneficiario->appendChild($atendimentoRN);

$nomeBeneficiario = $xml->createElement("ans:nomeBeneficiario", 'Fulano de Tal'); //nomeBeneficiario
$dadosBeneficiario->appendChild($nomeBeneficiario);

//contratadoExecutante
$contratadoExecutante = $xml->createElement("ans:contratadoExecutante");
$guiaConsulta->appendChild($contratadoExecutante);


$codigoPrestadorNaOperadora = $xml->createElement("ans:codigoPrestadorNaOperadora", '001'); //codigoPrestadorNaOperadora
$contratadoExecutante->appendChild($codigoPrestadorNaOperadora);

$nomeContratado = $xml->createElement("ans:nomeContratado", 'Hospital Teste'); //nomeContratado
$contratadoExecutante->appendChild($nomeContratado);

$CNES = $xml->createElement("ans:CNES", '9999'); //CNES
$contratadoExecutante->appendChild($CNES);

//profissionalExecutante
$profissionalExecutante = $xml->createElement("ans:profissionalExecutante"); //profissionalExecutante
$guiaConsulta->appendChild($profissionalExecutante);

$nomeProfissional = $xml->createElement("ans:nomeProfissional", 'Médico Teste'); //nomeProfissional
$profissionalExecutante->appendChild($nomeProfissional);

$conselhoProfissional = $xml->createElement("ans:conselhoProfissional", '02'); //conselhoProfissional
$profissionalExecutante->appendChild($conselhoProfissional);

$numeroConselhoProfissional = $xml->createElement("ans:numeroConselhoProfissional", '1234'); //numeroConselhoProfissional
$profissionalExecutante->appendChild($numeroConselhoProfissional);

$UF = $xml->createElement("ans:UF", 'SP'); //UF
$profissionalExecutante->appendChild($UF);

$CBOS = $xml->createElement("ans:CBOS", '201115'); //CBOS
$profissionalExecutante->appendChild($CBOS);

//dadosAtendimento
$dadosAtendimento = $xml->createElement("ans:dadosAtendimento"); //dadosAtendimento
$guiaConsulta->appendChild($dadosAtendimento);

$tipoAtendimento = $xml->createElement("ans:tipoAtendimento", '05'); //tipoAtendimento
$dadosAtendimento->appendChild($tipoAtendimento);

$indicacaoAcidente = $xml->createElement("ans:indicacaoAcidente", '9'); //indicacaoAcidente
$dadosAtendimento->appendChild($indicacaoAcidente);


// Calculo o Hash - Você poderia gerar os dados, usar um (replace do PHP) para substituir as tags, e pegar apenas os dados
$_XML['hash_dados'] = '' 
$_XML['hash'] = md5($_XML['hash_dados']);	

	/* terceiro bloco */
	// ans:mensagemTISS / ans:epilogo
	$epilogo = $xml->createElement("ans:epilogo");
	$mensagemTISS->appendChild($epilogo);
	
		// ans:mensagemTISS / ans:epilogo / ans:hash
		$hash = $xml->createElement("ans:hash", $_XML['hash']);
		$epilogo->appendChild($hash);	

# Comando para salvar/gerar o arquivo XML TISS
# Geralmente o nome do arquivo é o HASH que foi calculado ou número do lote, pois são informações únicas.
# você pode usar as variáveis: $_XML['fatura_remessa'] . $_XML['hash']

$xml->save("xml_tiss.xml");


# Imprime / Gera o xml em tela
echo $xml->saveXML();
?>

Com o comando acima você terá o seguinte retorno: xml_tiss.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<ans:mensagemTISS xmlns:ds="http://www.w3.org/2000/09/xmldsig#" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:schemaLocation="http://www.ans.gov.br/padroes/tiss/schemas http://www.ans.gov.br/padroes/tiss/schemas/tissV3_03_01.xsd" 
xmlns:ans="http://www.ans.gov.br/padroes/tiss/schemas">
 <ans:cabecalho>
 <ans:identificacaoTransacao>
 <ans:tipoTransacao>ENVIO_LOTE_GUIAS</ans:tipoTransacao>
 <ans:sequencialTransacao>6658</ans:sequencialTransacao>
 <ans:dataRegistroTransacao>2018-01-18</ans:dataRegistroTransacao>
 <ans:horaRegistroTransacao>10:00:00</ans:horaRegistroTransacao>
 </ans:identificacaoTransacao>
 <ans:origem>
 <ans:identificacaoPrestador>0000000000000</ans:identificacaoPrestador>
 </ans:origem>
 <ans:destino>
 <ans:registroANS>111111</ans:registroANS>
 </ans:destino>
 <ans:Padrao>03.03.03</ans:Padrao>
 </ans:cabecalho>
 <ans:prestadorParaOperadora>
 <ans:loteGuias>
 <ans:numeroLote>123</ans:numeroLote>
 <ans:guiasTISS/>
 </ans:loteGuias>
 </ans:prestadorParaOperadora>
 <ans:epilogo>
 <ans:hash>calculo do HASH</ans:hash>
 </ans:epilogo>
</ans:mensagemTISS>

16 Thoughts on “Gerar XML Padrão TISS com PHP

  1. Douglas on 27 de abril de 2018 at 16:33 said:

    Call to undefined method stdClass::createAttributeNS() deu esse erro!

  2. Ola,

    Quando vc irá liberar a parte dos atendimentos no arquivo XML?

    Obrigado, Bruno.

    • Bruno, no exemplo já estou contemplando a geração de (1)um atendimento no XML, é só você ajustar a sua necessidade, por exemplo; criando um loop para gerar vários atendimentos no mesmo arquivo)

  3. Ótimo artigo Fabiano, parabéns!!!

    Gostei também do artigo http://blog.fabianobento.com.br/2018/02/criando-um-validador-tiss-usando-php/#comment-61038

    Poderia passar o link dos Arquivos por favor Amigo?

    Iria me ajudar muito… Desde já agradeço!

  4. Márcio Sampaio on 11 de junho de 2018 at 14:14 said:

    Olá Fabiano, tudo bem?

    Inicialmente, parabéns pelo post. Ele é bem simples e facil de entender.

    Entretanto, não localizei em nenhuma parte do código onde se usa os dados do atendimento, como nome do paciente, carteira, tipo de atendimento e etc… Teria como explicar essa parte? Obrigado de antemão.

    • Márcio, tem no exemplo os dados de um atendimento, é só você ajustar a sua necessidade, criando um (while/for) para gerar vários atendimentos no mesmo arquivo).

  5. Felipe Miranda de Lima on 13 de maio de 2019 at 08:30 said:

    Bom dia,

    Muito boa a sua postagem, porem usando seu código ao passar o xml em um validador recebo o seguinte retorno:

    identificacaoPrestador: Character content other than whitespace is not allowed because the content type is ‘element-only’. Linha 11
    – identificacaoPrestador: Faltando elemento obrigatorio. Falta informar ( CNPJ, CPF
    – guiasTISS: Faltando elemento obrigatorio. Falta informar ( guiaSP-SADT, guiaResumoInternacao

    Teria uma ideia do que pode ser ?

  6. Olá, Parabéns por essa postagem… vai me ajudar muito.

    Os links para Download dos arquivos de exemplo não estão funcionando, poderia ajustar? Obrigado!

  7. Boa tarde!

    Favor verificar que, você não está utilizando os seguintes dados para a construção do XML:
    #Dados do atendimento e beneficiário
    #Dados do procedimento realizado

    Desta forma, não ficou claro onde esses dados devem estar estruturados para montar o Arquivo XML no DOM. Poderia ajustar isso, se não for pedir muito? Desta forma, vai me ajudar também.

    Obrigado!

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.

Post Navigation