---
# System prepended metadata

title: TISS Solicitação de Procedimento — Postman

---

# TISS Solicitação de Procedimento — Postman

Como configurar uma chamada SOAP TISS 4.01.00 contra o ambiente de
homologação Unimed RJ. Todo este doc foi escrito a partir de testes reais
contra o endpoint — não é especulação.

> **Só quer importar e usar?** Veja
> [IMPORTAR_COLLECTION.md](IMPORTAR_COLLECTION.md) — passo-a-passo de 5
> minutos. O documento abaixo entra na anatomia técnica (estrutura do
> envelope, algoritmo de hash, códigos de erro).

## Conteúdo da pasta

```
tiss-solicitacao-procedimento/
├── README.md                  ← você está aqui (referência técnica)
├── IMPORTAR_COLLECTION.md     ← guia de importação no Postman
├── postman/
│   ├── collection.json        ← request + pre-request + tests
│   └── environment.json       ← variáveis de homologação
├── exemplos/
│   ├── request.xml            ← envelope SOAP que retornou HTTP 200
│   └── response.xml           ← resposta real do servidor
├── wsdl.xml                   ← WSDL do endpoint (referência offline)
└── test_hash.js               ← reproduz o algoritmo de hash em Node
```

## 1. Endpoint e autenticação

| Item | Valor |
|---|---|
| URL | `https://htz.unimedrj.coop.br/htzfoundation-HTZFoundationEJB/TISSSolicitacaoProcedimentoV_4_01_00WS` |
| Método | `POST` |
| Auth | Basic Auth |
| Usuário | código do prestador na operadora (12 dígitos) |
| Senha | senha do prestador |

> O WSDL está em `<URL>?wsdl`. **Não use `Savon.client(wsdl: ...)`** — o WSDL
> publica o endpoint interno (`http://ferj-htz-01:80/...`); aponte direto
> para a URL pública.

## 2. Headers obrigatórios

| Header | Valor |
|---|---|
| `Content-Type` | `text/xml; charset=utf-8` |
| `SOAPAction` | `""` (duas aspas, vazio) |
| `Accept` | `text/xml` |

## 3. Estrutura do envelope

A estrutura desse endpoint **não segue o padrão TISS 3.x** (com
`prestadorParaOperadora` e `epilogo`). É a estrutura achatada do TISS 4.01:

```
solicitacaoProcedimentoWS
├── cabecalho
├── solicitacaoProcedimento
│   └── solicitacaoSP-SADT (ou solicitacaoInternacao / Prorrogacao / Odontologia)
└── hash                        ← direto, sem epilogo
```

**Namespace correto**: `http://www.ans.gov.br/padroes/tiss/schemas`
(NÃO use `http://ans.gov.br` — o servidor rejeita com `does not contain
operation meta data`).

## 4. Body — XML completo

Cole no Postman em **Body → raw → XML**. Variáveis `{{...}}` vêm do
Environment (próximo passo).

```xml
<soapenv:Envelope
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ans="http://www.ans.gov.br/padroes/tiss/schemas">
  <soapenv:Header/>
  <soapenv:Body>
    <ans:solicitacaoProcedimentoWS>
      <ans:cabecalho>
        <ans:identificacaoTransacao>
          <ans:tipoTransacao>SOLICITACAO_PROCEDIMENTOS</ans:tipoTransacao>
          <ans:sequencialTransacao>{{sequencial}}</ans:sequencialTransacao>
          <ans:dataRegistroTransacao>{{data_hoje}}</ans:dataRegistroTransacao>
          <ans:horaRegistroTransacao>{{hora_agora}}</ans:horaRegistroTransacao>
        </ans:identificacaoTransacao>
        <ans:origem>
          <ans:identificacaoPrestador>
            <ans:codigoPrestadorNaOperadora>{{codigo_prestador}}</ans:codigoPrestadorNaOperadora>
          </ans:identificacaoPrestador>
        </ans:origem>
        <ans:destino>
          <ans:registroANS>{{registro_ans}}</ans:registroANS>
        </ans:destino>
        <ans:Padrao>4.01.00</ans:Padrao>
      </ans:cabecalho>
      <ans:solicitacaoProcedimento>
        <ans:solicitacaoSP-SADT>
          <ans:cabecalhoSolicitacao>
            <ans:registroANS>{{registro_ans}}</ans:registroANS>
            <ans:numeroGuiaPrestador>{{numero_guia}}</ans:numeroGuiaPrestador>
          </ans:cabecalhoSolicitacao>
          <ans:tipoEtapaAutorizacao>2</ans:tipoEtapaAutorizacao>
          <ans:dadosBeneficiario>
            <ans:numeroCarteira>{{carteira}}</ans:numeroCarteira>
            <ans:atendimentoRN>N</ans:atendimentoRN>
          </ans:dadosBeneficiario>
          <ans:dadosSolicitante>
            <ans:contratadoSolicitante>
              <ans:codigoPrestadorNaOperadora>{{codigo_prestador}}</ans:codigoPrestadorNaOperadora>
            </ans:contratadoSolicitante>
            <ans:nomeContratadoSolicitante>{{nome_prestador}}</ans:nomeContratadoSolicitante>
            <ans:profissionalSolicitante>
              <ans:nomeProfissional>{{nome_profissional}}</ans:nomeProfissional>
              <ans:conselhoProfissional>06</ans:conselhoProfissional>
              <ans:numeroConselhoProfissional>{{crm}}</ans:numeroConselhoProfissional>
              <ans:UF>33</ans:UF>
              <ans:CBOS>{{cbos}}</ans:CBOS>
            </ans:profissionalSolicitante>
          </ans:dadosSolicitante>
          <ans:caraterAtendimento>1</ans:caraterAtendimento>
          <ans:dataSolicitacao>{{data_hoje}}</ans:dataSolicitacao>
          <ans:procedimentosSolicitados>
            <ans:procedimento>
              <ans:codigoTabela>22</ans:codigoTabela>
              <ans:codigoProcedimento>{{cod_procedimento}}</ans:codigoProcedimento>
              <ans:descricaoProcedimento>{{desc_procedimento}}</ans:descricaoProcedimento>
            </ans:procedimento>
            <ans:quantidadeSolicitada>1</ans:quantidadeSolicitada>
          </ans:procedimentosSolicitados>
          <ans:dadosExecutante>
            <ans:codigonaOperadora>{{codigo_prestador}}</ans:codigonaOperadora>
            <ans:CNES>{{cnes}}</ans:CNES>
          </ans:dadosExecutante>
        </ans:solicitacaoSP-SADT>
      </ans:solicitacaoProcedimento>
      <ans:hash>{{hash}}</ans:hash>
    </ans:solicitacaoProcedimentoWS>
  </soapenv:Body>
</soapenv:Envelope>
```

### Observações estruturais (descobertas em teste)

- `tipoTransacao` é `SOLICITACAO_PROCEDIMENTOS` (com **S** no final).
- Em `dadosSolicitante`, a ordem é: `contratadoSolicitante`,
  `nomeContratadoSolicitante` (obrigatório, **minLength=1**, não pode ser
  vazio), `profissionalSolicitante`.
- Em `procedimentosSolicitados`, `quantidadeSolicitada` é **irmão** de
  `procedimento`, não filho.
- `UF` aceita código numérico (`33` = RJ).
- `CBOS` é a classificação do médico (ex: `225335` clínico geral).
- `tipoEtapaAutorizacao` = `2` (solicitação).

## 5. Environment (variáveis)

Cria um Environment no Postman com:

| Variable | Exemplo (homologação) |
|---|---|
| `endpoint` | `https://htz.unimedrj.coop.br/htzfoundation-HTZFoundationEJB/TISSSolicitacaoProcedimentoV_4_01_00WS` |
| `usuario` | `097200011100` |
| `senha` | (current value, não initial) |
| `codigo_prestador` | `097200011100` |
| `registro_ans` | `312363` |
| `nome_prestador` | `UNIMED` |
| `nome_profissional` | `teste` |
| `crm` | `52458444` |
| `cbos` | `225335` |
| `cnes` | `7402074` |
| `cod_procedimento` | `40304361` |
| `desc_procedimento` | `Hemograma com contagem de plaquetas ou frações` |
| `carteira` | `09720210626000547` |
| `sequencial` | `989898` |
| `numero_guia` | (gerado a cada envio — ver script) |

> **Senha em "Current value", não "Initial"** — Initial sincroniza pra
> workspace compartilhado.

## 6. Authorization

Aba **Authorization** → Type **Basic Auth**:
- Username: `{{usuario}}`
- Password: `{{senha}}`

## 7. Pre-request Script (calcula hash + timestamps + guia)

Esta é a parte que faz tudo funcionar. **Sem este script o servidor
retorna `O hash calculado difere do informado`.**

```javascript
// 1. Timestamps no formato TISS
const now = new Date();
const pad = n => String(n).padStart(2, '0');
pm.environment.set('data_hoje',
  `${now.getFullYear()}-${pad(now.getMonth()+1)}-${pad(now.getDate())}`);
pm.environment.set('hora_agora',
  `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`);

// 2. Número de guia único (timestamp últimos 9 dígitos)
pm.environment.set('numero_guia',
  String(Date.now()).slice(-9));

// 3. Calcula hash MD5 do conteúdo
//    Algoritmo TISS: text nodes do solicitacaoProcedimentoWS
//    (excluindo o próprio hash), encoding ISO-8859-1, MD5 hex.
let body = pm.request.body.raw;
body = pm.variables.replaceIn(body);

// Pega só o conteúdo do solicitacaoProcedimentoWS, sem a tag <ans:hash>
const m = body.match(/<ans:solicitacaoProcedimentoWS>([\s\S]*)<ans:hash>/);
if (!m) throw new Error('Não achou solicitacaoProcedimentoWS no body');
const miolo = m[1];

// Remove todas as tags, sobram só os text nodes concatenados
const concat = miolo
  .replace(/<[^>]+>/g, '')   // tira tags
  .replace(/\s*\n\s*/g, '')  // tira quebras de linha + indentação
  .trim();

// MD5 em Latin-1 (ISO-8859-1) — CryptoJS.enc.Latin1 mapeia char codes 0-255
const wordArray = CryptoJS.enc.Latin1.parse(concat);
const hash = CryptoJS.MD5(wordArray).toString();
pm.environment.set('hash', hash);
```

### Por que ISO-8859-1?

Descoberto por engenharia reversa: enviamos um hash deliberadamente
errado, o servidor responde com o hash que ele calculou
(`Conteúdo esperado: <md5>`). Reproduzir esse hash exigiu encoding
**Latin-1**, não UTF-8. Caracteres como `ç`, `ã`, `é` mudam de bytes
entre UTF-8 e Latin-1 — usar UTF-8 falha sempre que a descrição do
procedimento tem acento.

## 8. Tests (validação da resposta)

```javascript
pm.test('HTTP 200', () => pm.response.to.have.status(200));

const body = pm.response.text();

pm.test('Não é SOAP Fault', () =>
  pm.expect(body).to.not.include('<env:Fault'));

pm.test('Tem cabecalho de resposta', () =>
  pm.expect(body).to.include('RESPOSTA_SOLICITACAO'));

// Extrai número da guia da operadora se autorizada
const m = body.match(/<numeroGuiaOperadora>(\d+)<\/numeroGuiaOperadora>/);
if (m) console.log('Guia operadora:', m[1]);

// Extrai motivos de negativa, se houver
const negs = [...body.matchAll(/<descricaoGlosa>([^<]+)<\/descricaoGlosa>/g)];
if (negs.length) console.log('Negativas:', negs.map(n => n[1]));
```

## 9. Cenários e respostas (testados)

### 9.1 Sucesso técnico, negativa de negócio

`HTTP 200` com `RESPOSTA_SOLICITACAO`. A resposta vem com
`autorizacaoServico` e dentro de cada `servicoAutorizado` pode haver:

- `quantidadeAutorizada > 0` → autorizado
- `motivosNegativa` com `codigoGlosa` → negado

Códigos de glosa observados em homologação:

| Código | Descrição |
|---|---|
| `1212` | Atendimento/referência fora da vigência do contrato do prestador |
| `1402` | Procedimento não autorizado |
| `5007` (com `0012`) | Beneficiário repassado pré-pagamento |
| `5007` (com `0650`) | Guia já utilizada por outro documento |

### 9.2 SOAP Faults observados (e o que significam)

| Fault | Causa real |
|---|---|
| `does not contain operation meta data for: {http://ans.gov.br}solicitacaoProcedimentoWS` | Namespace errado — use `http://www.ans.gov.br/padroes/tiss/schemas` |
| `O conteúdo do elemento 'ans:epilogo' não está completo. Um dos seguintes elementos é esperado: {ans:hash}` | Está usando estrutura TISS 3.x. Esse endpoint não tem `epilogo` — `hash` é direto |
| `O elemento 'ans:profissionalSolicitante' lido não é esperado. É esperado o elemento 'ans:nomeContratadoSolicitante'` | Falta `<ans:nomeContratadoSolicitante>` (obrigatório, minLength=1) |
| `O conteúdo do elemento 'ans:procedimentosSolicitados' não está completo. Um dos seguintes elementos é esperado: {ans:quantidadeSolicitada}` | `quantidadeSolicitada` está aninhada dentro de `procedimento`. Tem que ser irmã |
| `Value '' with length = '0' is not facet-valid with respect to minLength '1'` | Algum campo string obrigatório está vazio |
| `O hash calculado difere do informado na mensagem. Conteúdo lido: <X>. Conteúdo esperado: <Y>` | Hash incorreto. **Use a resposta** — ela traz o hash que o servidor calculou |

## 10. Receita rápida pra debugar

1. Mensagem de SOAP fault sempre dá pista clara — leia a `faultstring`.
2. Se reclamar de hash, a resposta do servidor traz o hash esperado, então
   dá pra reverter o algoritmo (foi exatamente como descobrimos
   ISO-8859-1).
3. Se reclamar de schema, o erro vem com o nome exato do elemento e o
   esperado.
4. Se HTTP 200 + `RESPOSTA_SOLICITACAO` + `motivosNegativa`, a integração
   técnica está OK — problema é de negócio (contrato, cobertura, etc.).

## 11. Resumo do fluxo descoberto

1. **Auth**: Basic Auth com user = código prestador, sem mTLS.
2. **Schema validation**: rigoroso, XSD do TISS 4.01.00.
3. **Hash**: MD5 dos text nodes em Latin-1.
4. **Resposta**: TISS `autorizacaoProcedimentoWS` com `RESPOSTA_SOLICITACAO`.
5. **Cloudflare na frente**: TLS é terminado lá, sem problemas com
   certificados.
