QR Code Check-in
Valide QR Codes na entrada e registre check-ins. Suporta também estorno (PATCH) no mesmo dia.
POST
/api/v1/api-qrcode-checkinRealiza check-in via QR Code (single ou combo) e retorna o pedido completo no mesmo formato dos vouchers.
Check-in Automático
Ao enviar o QR Code, o check-in é realizado automaticamente. A resposta retorna o pedido completo, com lote(s) e pessoa(s) já marcadas como check-in realizado.
Três modos de entrada
A API aceita três formas de identificar o que vai ser queimado — escolha uma por requisição:
- QR único:
{ "qr_code": "EPR9638OS07B75" }— single, combo ou unidade de adicional. - Vários QRs em lote:
{ "qr_code": "US6BNUMJHQ7J4P,US6BNUMJH27J4P" }— separados por vírgula. Cada um é processado individualmente (single/combo/adicional) e a resposta trazresultados[]com sucesso/erro por item. - Pedido inteiro:
{ "numero_pedido": "20260512-1234" }— queima todas as pessoas pendentes do pedido de uma vez (sem precisar listar cada QR).
qr_code e numero_pedido juntos retorna erro AMBIGUOUS_INPUT (400).Mesmo formato do endpoint de Vouchers
Esta API retorna o mesmo shape hierárquico (
pedido > lote(s) > pessoa(s)) e a mesma nomenclatura snake_case do endpoint /api/v1/api-vouchers. Use o mesmo parser para os dois endpoints.QR Codes de Combo
Combos com modo
unico possuem um QR code de grupo (formato YYYYMMDD-NNNN) e QR codes individuais por pessoa. Ao enviar o QR code de combo, a API realiza o check-in de todos os participantes de uma vez e retorna o pedido completo com lotes[] agrupados, pessoas[] dentro de cada lote, e adicionais[]. Se todos já fizeram check-in, retorna erro TICKET_ALREADY_USED (409).Autenticação
Permissão necessária: vouchers:checkin ou checkin ou all
Parâmetros
Request Body (JSON)
| Parâmetro | Tipo | Descrição |
|---|---|---|
qr_code | string | QR individual, QR de combo (YYYYMMDD-NNNN), unidade de adicional (14 chars), ou vários separados por vírgula. Obrigatório se numero_pedido não for enviado. |
numero_pedido | string | Número do pedido (ex: 20260512-1234) — queima todas as pessoas pendentes desse pedido. Obrigatório se qr_code não for enviado. Mutuamente exclusivo com qr_code. |
terminal | string | Identificador do dispositivo/catraca (ex: Catraca 01) |
operador | string | Nome do operador que realizou o check-in |
Outros Exemplos
Check-in sem terminal/operador
curl -X POST "https://api.omniticketz.com/v1/api-qrcode-checkin" \
-H "X-API-Key: sk_live_SUA_CHAVE_AQUI" \
-H "Content-Type: application/json" \
-d '{ "qr_code": "EPR9638OS07B75" }'Check-in em lote (vários QRs por vírgula)
curl -X POST "https://api.omniticketz.com/v1/api-qrcode-checkin" \
-H "X-API-Key: sk_live_SUA_CHAVE_AQUI" \
-H "Content-Type: application/json" \
-d '{
"qr_code": "US6BNUMJHQ7J4P,US6BNUMJH27J4P,EPR9638OS07B75",
"terminal": "Catraca 012",
"operador": "Lorrany Silva"
}'200Resposta — batch de QRs (3 enviados, 2 sucessos, 1 falha)
{
"success": true,
"data": {
"message": "Check-in em lote: 2 sucesso(s), 1 falha(s).",
"total_enviados": 3,
"total_sucesso": 2,
"total_falha": 1,
"resultados": [
{
"qr_code": "US6BNUMJHQ7J4P",
"success": true,
"status": 200,
"message": "Check-in realizado com sucesso.",
"pedido": { /* pedido completo */ }
},
{
"qr_code": "US6BNUMJH27J4P",
"success": true,
"status": 200,
"message": "Check-in realizado com sucesso.",
"pedido": { /* pedido completo */ }
},
{
"qr_code": "EPR9638OS07B75",
"success": false,
"status": 409,
"error": {
"code": "TICKET_ALREADY_USED",
"message": "Ingresso já utilizado em 14/05/2026 às 09:12.",
"details": { "qr_code": "EPR9638OS07B75", "checkin_em": "2026-05-14T12:12:00Z" }
}
}
]
}
}Comportamento do batch
- Códigos duplicados são dedupeados automaticamente (mesmo QR enviado 2x roda só 1x).
- Cada item é processado pelo mesmo dispatcher do modo single — combos e adicionais funcionam dentro do batch.
- Falha em um QR não derruba os outros: a resposta sempre vem
200e cada item tem seu própriosuccess/error. - Quando você envia apenas 1 QR (sem vírgula), o shape antigo é mantido —
resultados[]só aparece com 2+ códigos. - Processamento é sequencial (não paralelo) pra evitar race em logs de auditoria.
Check-in de um pedido inteiro (numero_pedido)
curl -X POST "https://api.omniticketz.com/v1/api-qrcode-checkin" \
-H "X-API-Key: sk_live_SUA_CHAVE_AQUI" \
-H "Content-Type: application/json" \
-d '{
"numero_pedido": "20260512-1234",
"terminal": "Catraca 012",
"operador": "Lorrany Silva"
}'200Resposta — check-in por numero_pedido
{
"success": true,
"data": {
"message": "Check-in realizado para 4 pessoa(s) do pedido.",
"numero_pedido": "20260512-1234",
"total_checkins": 4,
"total_pessoas": 4,
"pedido": {
"numero_pedido": "20260512-1234",
"status": "pago",
"cliente": { "nome": "Matheus Nattan", "email": "matheus@email.com" },
"lotes": [
{
"ingresso_id": "d5b759f4-...",
"lote_mestre_id": "abc123-...",
"nome_ingresso": "Ingresso - DayUse",
"nome_lote": "Adulto (11 anos ou mais)",
"data_uso": "2026-05-14",
"checkin_realizado": true,
"checkin_em": "2026-05-14T16:45:00Z",
"checkin_dispositivo": "Catraca 012",
"checkin_operador": "Lorrany Silva",
"dados": [
{ "qr_code": "US6BNUMJHQ7J4P", "Nome Completo": "Participante 1" },
{ "qr_code": "US6BNUMJH27J4P", "Nome Completo": "Participante 2" }
]
}
]
}
}
}Regras do modo numero_pedido
- Pedido precisa estar com
status = pago. Cancelado/reembolsado retornaORDER_NOT_PAID(422). - Pedido precisa pertencer ao tenant da API Key. Caso contrário,
ORDER_NOT_FOUND(404). - Se todas as pessoas já fizeram check-in, retorna
TICKET_ALREADY_USED(409). - Adicionais NÃO são processados — eles têm QRs próprios (14 chars). Para queimar adicionais junto, envie os QRs deles via
qr_code(batch por vírgula).
Resposta — Combo
Quando o QR enviado é um combo (formato YYYYMMDD-NNNN):
200Check-in de Combo (todos os participantes)
{
"success": true,
"data": {
"message": "Check-in realizado para 3 pessoa(s) do combo.",
"combo_qr_code": "20260415-3904",
"total_checkins": 3,
"total_pessoas": 3,
"pedido": {
"numero_pedido": "20260415-3904",
"pago_em": "2026-04-15T11:26:18Z",
"origem": "online",
"total": 235.78,
"cliente": { "nome": "Maria Silva", "email": "maria.silva@example.com" },
"lotes": [
{
"ingresso_id": "d5b759f4-...",
"lote_mestre_id": "abc123-...",
"categoria": "outros",
"nome_ingresso": "Ingresso - DayUse",
"nome_lote": "Adulto",
"data_uso": "2026-04-15",
"quantidade": 3,
"valor_unitario": 71.96,
"subtotal": 215.88,
"pessoas": [
{
"qr_code": "US-SO4H9C4WDZ",
"nome": "Maria Silva",
"checkin_realizado": true,
"checkin_em": "2026-04-15T11:34:23Z",
"checkin_dispositivo": "Catraca 012",
"checkin_operador": "Lorrany Silva"
}
]
}
],
"adicionais": [
{ "nome": "Almoço Buffet Livre", "quantidade": 2, "preco_unitario": 45.00, "subtotal": 90.00 }
]
}
}
}Códigos de Erro
Envelope de erro padrão
Todos os erros seguem o mesmo envelope da Integration API:
{ success: false, error: { code, message, details? } }.Erros possíveis
| Parâmetro | Tipo | Descrição |
|---|---|---|
TICKET_NOT_FOUND | 404 | QR Code não encontrado ou não pertence ao tenant |
TICKET_ALREADY_USED | 409 | Ingresso já foi utilizado (single), todos os participantes do combo já fizeram check-in, ou todas as pessoas do pedido já fizeram check-in (modo numero_pedido) |
TICKET_EXPIRED | 410 | Ingresso era válido para data passada |
TICKET_NOT_VALID_YET | 422 | Ingresso válido para data futura |
TICKET_CANCELLED | 403 | Ingresso cancelado, expirado ou reembolsado |
ORDER_NOT_FOUND | 404 | numero_pedido informado não existe ou não pertence ao tenant |
ORDER_NOT_PAID | 422 | numero_pedido informado está com status diferente de 'pago' |
NO_PEOPLE | 422 | numero_pedido informado não tem pessoas (ingressos) para check-in |
AMBIGUOUS_INPUT | 400 | Body contém qr_code E numero_pedido ao mesmo tempo — envie apenas um |
PERMISSION_DENIED | 403 | API Key não tem permissão para check-in |
MISSING_API_KEY | 401 | Header X-API-Key ausente |
INVALID_API_KEY | 401 | API Key inválida ou expirada |
MISSING_FIELD | 400 | Body sem qr_code nem numero_pedido |
INTERNAL_ERROR | 500 | Erro inesperado no servidor |
409Combo - todos já fizeram check-in
{
"success": false,
"error": {
"code": "TICKET_ALREADY_USED",
"message": "Todos os 3 participantes do combo já realizaram check-in.",
"details": {
"combo_qr_code": "20260415-3904",
"total_pessoas": 3
}
}
}410Ingresso expirado
{
"success": false,
"error": {
"code": "TICKET_EXPIRED",
"message": "Ingresso expirado. Era válido para 20/01/2026.",
"details": {
"data_ingresso": "2026-01-20",
"data_atual": "2026-01-22",
"qr_code": "EPR9638OS07B75"
}
}
}422Ingresso ainda não é válido
{
"success": false,
"error": {
"code": "TICKET_NOT_VALID_YET",
"message": "Ingresso válido apenas para 25/01/2026. Hoje é 24/01/2026.",
"details": {
"data_ingresso": "2026-01-25",
"qr_code": "EPR9638OS07B75"
}
}
}Dados salvos no banco (primeiro check-in)
checkin_realizado= truecheckin_em= data/hora do check-incheckin_dispositivo= valor do campo terminalcheckin_operador_externo= valor do campo operadorsistema_externo= true (sempre quando via API)
PATCH
/api/v1/api-qrcode-checkinEstorna um check-in realizado. Permitido apenas no mesmo dia.
Estorno apenas no mesmo dia
O estorno só é permitido no mesmo dia em que a leitura foi efetuada. Caso contrário, será retornado erro
ESTORNO_NAO_PERMITIDO.Estorno de Combo
Ao enviar um QR code de combo (formato
YYYYMMDD-NNNN), o estorno é realizado para todos os participantes que possuem check-in. Retorna a lista de estornados.Autenticação
Permissão necessária: vouchers:checkin ou checkin ou all
Parâmetros
Request Body (JSON)
| Parâmetro | Tipo | Descrição |
|---|---|---|
qr_code | string | QR individual, QR de combo (YYYYMMDD-NNNN), ou vários separados por vírgula. Obrigatório se numero_pedido não for enviado. |
numero_pedido | string | Número do pedido (ex: 20260512-1234) — estorna todas as pessoas com check-in feito no mesmo dia. Obrigatório se qr_code não for enviado. Mutuamente exclusivo com qr_code. |
terminal | string | Identificador do terminal que realizou o estorno |
operador | string | Nome do operador que realizou o estorno |
Estorno em lote (vírgula ou pedido inteiro)
curl -X PATCH "https://api.omniticketz.com/v1/api-qrcode-checkin" \
-H "X-API-Key: sk_live_SUA_CHAVE_AQUI" \
-H "Content-Type: application/json" \
-d '{
"qr_code": "US6BNUMJHQ7J4P,US6BNUMJH27J4P",
"terminal": "Catraca 012",
"operador": "Lorrany Silva"
}'Estorno por pedido — regras
- Pedido precisa pertencer ao tenant (
ORDER_NOT_FOUNDcaso contrário). - Pelo menos uma pessoa precisa ter check-in ativo — se nenhuma teve check-in, retorna
SEM_CHECKIN(422); se todas já foram estornadas, retornaJA_ESTORNADO(423). - Estorno só é permitido no mesmo dia do check-in (mesma regra do estorno single/combo).
Resposta — Combo
200Estorno de combo (todos os participantes)
{
"success": true,
"data": {
"message": "Estorno realizado para 3 pessoa(s) do combo.",
"combo_qr_code": "20260415-3904",
"total_estornados": 3,
"pedido": {
"numero_pedido": "20260415-3904",
"pessoas": [
{
"qr_code": "US-SO4H9C4WDZ",
"nome": "Maria Silva",
"estornado_em": "2026-04-15T11:28:34.320Z",
"estorno_dispositivo": "Catraca 012",
"estorno_operador": "Lorrany Silva"
}
]
}
}
}Campos da Resposta (estorno)
data
| Parâmetro | Tipo | Descrição |
|---|---|---|
message | string | Mensagem descritiva do resultado |
combo_qr_code | string | Apenas em combo: QR de grupo estornado |
total_estornados | number | Apenas em combo: quantidade de estornos realizados |
pedido | object | Pedido com pessoa (single) ou pessoas[] (combo) |
Pessoa (pedido.pessoa ou pedido.pessoas[])
| Parâmetro | Tipo | Descrição |
|---|---|---|
qr_code | string | Código QR do ingresso |
nome | string | Nome da pessoa |
estornado_em | string | Data/hora do estorno (ISO 8601) |
estorno_dispositivo | string | Terminal que realizou o estorno |
estorno_operador | string | Operador que realizou o estorno |
Códigos de Erro
Erros possíveis
| Parâmetro | Tipo | Descrição |
|---|---|---|
ESTORNO_NAO_PERMITIDO | 422 | Estorno só é permitido no mesmo dia do check-in |
SEM_CHECKIN | 422 | Ingresso (ou combo/pedido inteiro) existe, mas nunca teve check-in — não há o que estornar |
JA_ESTORNADO | 423 | O check-in já foi estornado anteriormente. Status 423 é exclusivo deste erro. details traz estornado_em, estorno_operador e estorno_terminal do estorno original |
TICKET_NOT_FOUND | 404 | QR Code não encontrado |
ORDER_NOT_FOUND | 404 | numero_pedido informado não existe ou não pertence ao tenant |
AMBIGUOUS_INPUT | 400 | Body contém qr_code E numero_pedido ao mesmo tempo — envie apenas um |
MISSING_FIELD | 400 | Body sem qr_code nem numero_pedido |
TENANT_MISMATCH | 403 | Ingresso não pertence a este tenant |
SEM_CHECKIN vs JA_ESTORNADO
Os dois erros significam "não há check-in ativo para estornar", mas a causa é diferente — e a API agora os separa para você reagir certo:
SEM_CHECKIN(422) — o ingresso nunca passou por check-in.JA_ESTORNADO(423) — o ingresso teve check-in, mas ele já foi estornado antes. Odetailstraz quando/quem/qual terminal fez o estorno original.
numero_pedido, o JA_ESTORNADO só dispara quando todas as pessoas já foram estornadas.422SEM_CHECKIN — ingresso nunca teve check-in
{
"success": false,
"error": {
"code": "SEM_CHECKIN",
"message": "Este ingresso nunca teve check-in, portanto não há o que estornar.",
"details": { "qr_code": "EPR9638OS07B75" }
}
}423JA_ESTORNADO — check-in já foi estornado antes
{
"success": false,
"error": {
"code": "JA_ESTORNADO",
"message": "O check-in deste ingresso já foi estornado anteriormente.",
"details": {
"qr_code": "ACYJPUGS7QWZMR",
"estornado_em": "2026-05-16T15:59:41.003Z",
"estorno_operador": "Lorrany Silva",
"estorno_terminal": "Catraca 012"
}
}
}
