Fluxo de verificação de hóspedes
Este guia explica como usar a lista de hóspedes no hotel em um captive portal: como comparar o que o hóspede digita com a lista, quando a sessão de Wi-Fi deve terminar, com que frequência atualizar a lista e quais campos guardar para os registros exigidos pela Lei turca nº 5651.
O que pedir no portal#
Como a lista traz os dados do quarto e de identificação juntos, o formulário mais comum é número do quarto + sobrenome. Só o número do quarto não basta; qualquer pessoa que soubesse o número de um quarto vizinho conseguiria fazer login. As alternativas são número do quarto + número do documento/passaporte ou sobrenome + data de nascimento; mantenha esta última como opção reserva para hóspedes sem número de documento.
Regras de correspondência#
Normalize os dois lados antes de comparar o que o hóspede digitou com os valores da lista:
- Número do quarto: remova espaços nas extremidades e converta para maiúsculas.
roomNameé uma string (pode ser"104","A-12"ou"Villa 3"); não a converta para número nem remova zeros à esquerda. - Sobrenome: converta para maiúsculas (atenção ao mapeamento turco
i → İ) e reduza espaços repetidos a um só. Os valores da lista geralmente são lidos do documento de identidade, em maiúsculas. - Número do documento: remova os espaços e converta para maiúsculas. O número de identidade nacional turco tem 11 dígitos; o número do passaporte mistura letras e dígitos.
- Data de nascimento: a lista usa
DD.MM.YYYY; converta se o seu formulário coletar outro formato.
const norm = (s) => String(s ?? "")
.replace(/\s+/g, " ")
.trim()
.toLocaleUpperCase("tr-TR");
function findGuest(list, room, lastName) {
return list.find((g) =>
norm(g.roomName) === norm(room) && norm(g.lastName) === norm(lastName)
) || null;
}
const guest = findGuest(data.otelde, form.room, form.lastName);
if (!guest) {
// "Número do quarto e sobrenome não conferem" — conte as tentativas falhas e limite após 5
}O valor unique do registro correspondente é a identidade do usuário no hotspot. Quando o mesmo hóspede fizer login a partir de um segundo dispositivo, reutilize a conta vinculada a esse valor em vez de criar uma nova, e aplique o limite de dispositivos nessa conta.
Duração da sessão#
checkout é a data prevista de check-out e aponta para 00:00 (UTC) desse dia; não inclui horário. Se você liberar a sessão até esse momento, o hóspede perde o acesso na madrugada do dia da partida. Calcule o fim da sessão somando à data o horário de check-out do hotel:
const CHECKOUT_TIME = "12:00"; // horário de check-out do hotel
const day = new Date(guest.checkout * 1000)
.toLocaleDateString("en-CA", { timeZone: "UTC" }); // "2026-09-10"
const sessionEnd = new Date(`${day}T${CHECKOUT_TIME}:00+03:00`);Se o hóspede sair antes do horário de check-out, ele deixa de aparecer na lista; encerre a conta na próxima sincronização. Se a estadia for estendida, checkout muda; compare esse campo durante a sincronização e atualize o fim da sessão. Em check-outs tardios, é mais seguro manter o acesso liberado enquanto o hóspede continuar na lista.
Sincronização periódica#
A lista é um retrato do momento; não há notificação de mudanças (webhook). Busque a lista em um intervalo fixo e compare-a com a anterior pelo unique:
- Intervalo: 5 minutos bastam para a maioria dos hotéis. Se os hóspedes precisarem se conectar logo no check-in, você pode reduzir para 1–2 minutos; não use menos de 1 minuto.
uniquenovo: prepare a conta; a correspondência com o hóspede acontece no primeiro login no portal.uniqueausente: o hóspede fez check-out ou a reserva foi cancelada. Encerre a sessão e feche a conta.- Mesmo
unique,roomNameoucheckoutdiferente: troca de quarto ou extensão da estadia. Atualize a conta. - Requisição com falha: em caso de timeout,
401ou5xx, mantenha a última lista obtida com sucesso; nunca feche contas com base em uma resposta de erro.
async function sync(prev) {
const res = await fetch(BASE + "/public/json/customer/inhotel", {
method: "POST",
headers: { "ApiKey": process.env.HMS_API_KEY, "HotelCode": HOTEL_CODE }
});
if (!res.ok) return prev; // 401 / 5xx: mantém a lista anterior
const { success, otelde } = await res.json();
if (success !== 1) return prev;
const next = new Map(otelde.map((g) => [g.unique, g]));
for (const [id] of prev) {
if (!next.has(id)) await closeAccount(id); // fez check-out
}
for (const [id, g] of next) {
const old = prev.get(id);
if (!old) await openAccount(g); // hóspede novo
else if (old.checkout !== g.checkout || old.roomName !== g.roomName) await updateAccount(g);
}
return next;
}Vários hóspedes no mesmo quarto#
Cada hóspede de um quarto é um registro separado: o rezervasyon_id é compartilhado e o unique é diferente. Abra contas por hóspede, e não por quarto, para que cada hóspede tenha seu próprio dispositivo, sessão e registro da Lei 5651. Uma busca por número do quarto + sobrenome pode retornar mais de um registro quando os hóspedes têm o mesmo sobrenome (uma família); em vez de pegar a primeira correspondência, diferencie pelo nome ou pela data de nascimento, ou abra uma conta compartilhada para eles.
Registros da Lei 5651#
A obrigação de manter registros de acesso segundo a Lei turca nº 5651 é do sistema de hotspot; o HMS apenas fornece os dados de identificação. Quando uma sessão for aberta, armazene os campos a seguir junto com o endereço MAC/IP e o horário: unique, rezervasyon_id, firstName, lastName, identityNumber, birthDate, roomName, checkin, checkout. Depois que o hóspede sai da lista, o HMS deixa de fornecer essas informações; mantenha o registro do seu lado.