OmniTicketz

    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-checkin

    Realiza 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 traz resultados[] 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).
    Enviar 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âmetroTipoDescrição
    qr_code
    stringQR 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
    stringNú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
    stringIdentificador do dispositivo/catraca (ex: Catraca 01)
    operador
    stringNome 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 200 e cada item tem seu próprio success/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 retorna ORDER_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âmetroTipoDescrição
    TICKET_NOT_FOUND
    404QR Code não encontrado ou não pertence ao tenant
    TICKET_ALREADY_USED
    409Ingresso 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
    410Ingresso era válido para data passada
    TICKET_NOT_VALID_YET
    422Ingresso válido para data futura
    TICKET_CANCELLED
    403Ingresso cancelado, expirado ou reembolsado
    ORDER_NOT_FOUND
    404numero_pedido informado não existe ou não pertence ao tenant
    ORDER_NOT_PAID
    422numero_pedido informado está com status diferente de 'pago'
    NO_PEOPLE
    422numero_pedido informado não tem pessoas (ingressos) para check-in
    AMBIGUOUS_INPUT
    400Body contém qr_code E numero_pedido ao mesmo tempo — envie apenas um
    PERMISSION_DENIED
    403API Key não tem permissão para check-in
    MISSING_API_KEY
    401Header X-API-Key ausente
    INVALID_API_KEY
    401API Key inválida ou expirada
    MISSING_FIELD
    400Body sem qr_code nem numero_pedido
    INTERNAL_ERROR
    500Erro 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 = true
    • checkin_em = data/hora do check-in
    • checkin_dispositivo = valor do campo terminal
    • checkin_operador_externo = valor do campo operador
    • sistema_externo = true (sempre quando via API)
    PATCH/api/v1/api-qrcode-checkin

    Estorna 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âmetroTipoDescrição
    qr_code
    stringQR individual, QR de combo (YYYYMMDD-NNNN), ou vários separados por vírgula. Obrigatório se numero_pedido não for enviado.
    numero_pedido
    stringNú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
    stringIdentificador do terminal que realizou o estorno
    operador
    stringNome 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_FOUND caso 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, retorna JA_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âmetroTipoDescrição
    message
    stringMensagem descritiva do resultado
    combo_qr_code
    stringApenas em combo: QR de grupo estornado
    total_estornados
    numberApenas em combo: quantidade de estornos realizados
    pedido
    objectPedido com pessoa (single) ou pessoas[] (combo)

    Pessoa (pedido.pessoa ou pedido.pessoas[])

    ParâmetroTipoDescrição
    qr_code
    stringCódigo QR do ingresso
    nome
    stringNome da pessoa
    estornado_em
    stringData/hora do estorno (ISO 8601)
    estorno_dispositivo
    stringTerminal que realizou o estorno
    estorno_operador
    stringOperador que realizou o estorno

    Códigos de Erro

    Erros possíveis

    ParâmetroTipoDescrição
    ESTORNO_NAO_PERMITIDO
    422Estorno só é permitido no mesmo dia do check-in
    SEM_CHECKIN
    422Ingresso (ou combo/pedido inteiro) existe, mas nunca teve check-in — não há o que estornar
    JA_ESTORNADO
    423O 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
    404QR Code não encontrado
    ORDER_NOT_FOUND
    404numero_pedido informado não existe ou não pertence ao tenant
    AMBIGUOUS_INPUT
    400Body contém qr_code E numero_pedido ao mesmo tempo — envie apenas um
    MISSING_FIELD
    400Body sem qr_code nem numero_pedido
    TENANT_MISMATCH
    403Ingresso 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. O details traz quando/quem/qual terminal fez o estorno original.
    Em combo e 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"
        }
      }
    }
    OmniTicketz API Documentation