Інтеграція 1С-Бітрікс з ЄМІАС
ЄМІАС (Єдина медична інформаційно-аналітична система) — державна платформа охорони здоров'я Москви, що використовується міськими поліклініками та лікарнями. Інтеграція з ЄМІАС дозволяє сайту медичного закладу (або Держпослугам Москви) відображати реальний розклад лікарів та приймати онлайн-записи безпосередньо в систему, минаючи реєстратуру.
Робота з ЄМІАС — це взаємодія з державною системою: потрібна угода з Департаментом охорони здоров'я Москви, сертифікація, випуск сертифікатів доступу. Технічна інтеграція будується на вебсервісах ЄМІАС SOAP або REST.
Доступ до API ЄМІАС
Отримання доступу до API ЄМІАС — адміністративний процес:
- Заявка до Департаменту інформаційних технологій м. Москви (ДІТ)
- Підписання угоди про інформаційну взаємодію
- Випуск сертифіката для двостороннього TLS (mTLS)
- Отримання тестового стенду та документації
API ЄМІАС використовує WCF (Windows Communication Foundation) або REST залежно від версії та модуля. Для роботи з розкладом лікарів — сервіс ScheduleService.
SOAP-клієнт для ЄМІАС
Якщо ЄМІАС надає WSDL:
class EmiasClient
{
private \SoapClient $client;
private string $certPath;
private string $certPassword;
public function __construct(string $wsdlUrl, string $certPath, string $certPassword)
{
$this->certPath = $certPath;
$this->certPassword = $certPassword;
// ЄМІАС вимагає mTLS — клієнтський сертифікат
$context = stream_context_create([
'ssl' => [
'local_cert' => $certPath,
'passphrase' => $certPassword,
'verify_peer' => true,
'verify_peer_name' => true,
'cafile' => '/etc/ssl/certs/emias-ca.crt',
],
]);
$this->client = new \SoapClient($wsdlUrl, [
'soap_version' => SOAP_1_2,
'encoding' => 'UTF-8',
'trace' => false,
'exceptions' => true,
'stream_context' => $context,
]);
}
public function getDoctorSchedule(string $lpuCode, int $doctorId, \DateTime $date): array
{
try {
$result = $this->client->GetSchedule([
'lpuCode' => $lpuCode,
'doctorId' => $doctorId,
'dateFrom' => $date->format('Y-m-d'),
'dateTo' => $date->format('Y-m-d'),
]);
return $this->parseScheduleResult($result);
} catch (\SoapFault $e) {
\Bitrix\Main\Diag\Debug::writeToFile(
"EMIAS SOAP fault: {$e->faultcode} — {$e->faultstring}",
'',
'/local/logs/emias.log'
);
throw new \RuntimeException("Помилка ЄМІАС: {$e->faultstring}");
}
}
public function createAppointment(array $params): string
{
// Повертає appointmentId ЄМІАС
$result = $this->client->CreateAppointment([
'lpuCode' => $params['lpu_code'],
'doctorId' => $params['doctor_id'],
'slotId' => $params['slot_id'],
'patient' => [
'lastName' => $params['last_name'],
'firstName' => $params['first_name'],
'middleName' => $params['middle_name'] ?? '',
'birthDate' => $params['birth_date'], // DD.MM.YYYY
'snils' => $params['snils'], // Обов'язково для ЄМІАС
'oms' => $params['oms_policy'], // Поліс ОМС
],
]);
return (string)$result->AppointmentId;
}
}
СНІЛС та поліс ОМС — обов'язкові поля для запису в ЄМІАС. Це принципова відмінність від комерційних МІС, де достатньо номера телефону.
Верифікація пацієнта через Держпослуги
Оскільки ЄМІАС вимагає СНІЛС, інтеграція з Держпослугами (ЄСІА) для авторизації пацієнта — логічне продовження. Пацієнт авторизується через Держпослуги → система отримує його СНІЛС та дані з ЄСІА → передає в ЄМІАС.
class GosuslugiEsiaService
{
// ЄСІА OAuth 2.0
private string $clientId; // Мнемоніка ІС у ЄСІА
private string $certPath; // Сертифікат ІС для підпису запитів
public function getAuthUrl(string $state): string
{
$timestamp = date('Y.m.d H:i:s O');
$scope = 'openid fullname snils medical';
// ЄСІА вимагає підписаний запит
$clientSecret = $this->signRequest(implode('', [
$scope, $timestamp, $this->clientId, $state
]));
return 'https://esia.gosuslugi.ru/aas/oauth2/ac?' . http_build_query([
'client_id' => $this->clientId,
'client_secret' => $clientSecret,
'redirect_uri' => SITE_SERVER_NAME . '/esia/callback/',
'scope' => $scope,
'response_type' => 'code',
'state' => $state,
'timestamp' => $timestamp,
'access_type' => 'online',
]);
}
private function signRequest(string $data): string
{
// Підпис через openssl із сертифікатом ІС
$pkcs7 = '';
openssl_pkcs7_sign(
tempnam(sys_get_temp_dir(), 'esia_'),
tempnam(sys_get_temp_dir(), 'esia_out_'),
file_get_contents($this->certPath),
['', ''],
[],
PKCS7_DETACHED | PKCS7_NOATTR
);
return base64_encode($pkcs7);
}
}
Інтеграція з ЄСІА — окремий великий проект із вимогами до сертифікації системи.
Кешування та синхронізація розкладу
Прямі запити до ЄМІАС при кожному показі розкладу на сайті — неприйнятно з точки зору продуктивності та обмежень ЄМІАС. Розклад синхронізується в локальну таблицю кожні 5–15 хвилин:
class EmiasSyncAgent
{
public function syncSchedule(): string
{
$doctors = $this->getActiveDoctors(); // список лікарів з 1С-Бітрікс
$dateRange = [
'from' => date('Y-m-d'),
'to' => date('Y-m-d', strtotime('+30 days')),
];
foreach ($doctors as $doctor) {
try {
$schedule = $this->emiasClient->getDoctorSchedule(
$doctor['LPU_CODE'],
$doctor['EMIAS_DOCTOR_ID'],
new \DateTime($dateRange['from'])
);
$this->upsertSlots($doctor['ID'], $schedule);
} catch (\RuntimeException $e) {
// Логуємо, не переривамо цикл для інших лікарів
\CEventLog::Add(['SEVERITY' => 'WARNING', 'DESCRIPTION' => $e->getMessage()]);
}
}
return __FUNCTION__ . '();';
}
}
Слоти зберігаються в local_emias_slots: DOCTOR_ID, SLOT_DATE, SLOT_TIME, EMIAS_SLOT_ID, IS_FREE. Сайт читає слоти з локальної таблиці, а не з ЄМІАС безпосередньо.
Конфлікти одночасного запису
Користувач обрав слот на 15:00 → почав заповнювати форму → інший користувач записався на той самий час через портал ЄМІАС. Рішення:
- При відкритті форми — «м'яке» резервування слоту (позначка в локальній таблиці)
- Резерв діє 5 хвилин
- При остаточному надсиланні — запис у API ЄМІАС
- Якщо ЄМІАС повернув помилку «слот зайнятий» — показуємо найближчі вільні
Склад робіт
- Отримання доступу до API ЄМІАС (адміністративний процес, не розробка)
- Налаштування mTLS, клієнтський сертифікат
- SOAP-клієнт ЄМІАС, парсинг розкладу
- Синхронізація розкладу в локальну таблицю (агент)
- Компонент запису з формою СНІЛС/поліс ОМС
- Інтеграція з ЄСІА для авторизації (опціонально, окремий проект)
- Обробка конфліктів одночасного запису
Терміни: адміністративні процедури (доступ, угода) — 1–3 місяці. Технічна розробка після отримання доступу — 6–12 тижнів.







