ГИС ЭП Электронная Путёвка: что нужно знать туроператорам в 2026

Веб Штурм
  • ГИС ЭП
  • электронная путёвка
  • туристическая деятельность
  • 152-ФЗ
  • интеграции

ГИС ЭП — Государственная Информационная Система Электронная Путёвка — обязательный канал учёта электронных путёвок туроператоров. Каждая проданная путёвка должна быть зарегистрирована в ГИС, изменения статуса (аннуляция, возврат) — синхронизированы. На практике это значит, что система бронирования туроператора работает в связке с ГИС асинхронно: после успешной оплаты — формирование ЭП и отправка.

Что такое ГИС ЭП

Полная расшифровка: Государственная Информационная Система Электронная Путёвка. Назначение — централизованное формирование и учёт электронных путёвок на основе договоров реализации туристского продукта. Принимающие стороны:

Связка с другими системами:

Нормативная база

ДокументЧто регулирует
Закон «Об основах туристской деятельности»Обязанность туроператора формировать ЭП
Регламенты ГИС ЭПСтруктура данных, протоколы передачи
152-ФЗЗащита ПД туристов
132-ФЗОтветственность туроператора перед туристом

Технические требования

Архитектура нашей интеграции

Реализовано в системе бронирования речных круизов (production). Стек:

Workflow (упрощённо)

// hermes-stack/gis-ep-worker/src/workflows/issue-voucher.ts
export const issueElectronicVoucher = defineWorkflow(hatchet)
  .step('snapshot-order', async ({ input }) => {
    // Снимок данных тура + пассажира на момент формирования ЭП
    return { snapshot: await fetchOrderSnapshot(input.orderId) };
  })
  .step('build-payload', async ({ parentOutput }) => {
    return { payload: buildGISEPPayload(parentOutput.snapshot) };
  })
  .step('submit-to-gis', async ({ parentOutput }) => {
    const res = await gisEP.submit(parentOutput.payload, {
      apiKey: process.env.GIS_EP_API_KEY,
      idempotencyKey: input.orderId, // одна оплата = одна ЭП
    });
    if (res.code !== 'OK') throw new RetryableError(res.message);
    return { gisVoucherId: res.voucherId };
  })
  .step('persist-and-notify', async ({ parentOutput }) => {
    await db.orders.update(input.orderId, { gisVoucherId: parentOutput.gisVoucherId });
    await crmActivities.add({ kind: 'gis-ep:issued', orderId: input.orderId, ... });
  });

Типичные грабли при интеграции

ПроблемаЧто происходитКак избежать
Расхождения данных туриста между бронированием и ЭПТур забронирован на «Иванов», а в ЭП «Иванова» (опечатка после правки)Snapshot-pattern: фиксируем данные на момент формирования ЭП в отдельной таблице, не используем live-данные тура
Аннуляция тура без аннуляции ЭПЭП висит в ГИС со статусом «активна» при отменённом туре → штрафCompensating workflow: на каждое изменение статуса тура — соответствующий update в ГИС
Возврат — кто меняет статус ЭПВозврат через банк ≠ возврат через туроператораЧёткое разделение: бухгалтерский возврат и аннуляция ЭП — две разные операции, обе обязательны
Дубли ЭП при retryИдемпотентность не настроена → ГИС создаёт две путёвки → двойной учёт → штрафIdempotency-key = orderId (одна оплата = одна ЭП), серверная проверка existing voucherId перед отправкой
Отказы ГИС при пиковых нагрузкахАвария регистратора → весь worker зависает → новые туры не оформляютсяHatchet retry/backoff + DLQ + ручной интерфейс для разбора зависших

Связка ГИС ЭП с PDF-ваучером

Один и тот же тур порождает два документа:

  1. PDF-ваучер для туриста — печатный документ через PDFme (наш плагин cruise-pack даёт компоненты под речные круизы: схема палубы, расписание стоянок, маршрут). Хранится в Supabase Storage, ссылка /pdf/v/{shortToken} в email и SMS.
  2. Электронная путёвка в ГИС — машиночитаемый документ для гос-системы. Хранится в ГИС, в нашей БД только gisVoucherId для связи.

Оба формируются в одном Hatchet workflow после успешной оплаты — это гарантирует консистентность.

Что мы из этого вынесли

Ссылки