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>