1C-Bitrix ו-EMIAS: מבירוקרטיה ל-API עובד
EMIAS היא פלטפורמת הבריאות הממשלתית של מוסקבה למרפאות ובתי חולים. שילובה מאפשר לאתר המוסד הרפואי שלך להציג לוחות זמנים אמיתיים של רופאים ולקבל תורים מקוונים ישירות למערכת, תוך עקיפת דלפק הקבלה. המהנדסים שלנו ביצעו למעלה מ-15 פרויקטים כאלה, כולל מקרים מורכבים עם דרישות לא סטנדרטיות. לדוגמה, פוליקליניקה גדולה לא יכלה להעביר נתוני רופאים בגלל לקוח SOAP מיושן—שכתבנו את האינטגרציה מאפס, והאצנו את התורים פי 4 וחסכנו עד 40% מזמן הקבלה. פרויקט נוסף: רשת מרפאות עם 30 סניפים שילבה את EMIAS ו-Bitrix24—בתוך החודש הראשון, הזמנות מקוונות היוו 60% מכלל הביקורים, והעבודה הידנית צומצמה ב-70%.
הימנעו מטעויות נפוצות—הזמינו אינטגרציה מקצועית. כבר עברנו את הדרך הזו ואנחנו מוכנים לעזור לכם.
בעיות שאנחנו פותרים
- גישה איטית ל-API. קבלת גישה ל-API של EMIAS היא תהליך בירוקרטי הנמשך 1–3 חודשים. אנחנו מטפלים בבקשה, מסייעים עם התיעוד ומגדירים mTLS.
- מורכבות SOAP ו-mTLS. EMIAS משתמשת בשירותי WCF עם תעודות לקוח. יישום לקוח SOAP תקין דורש מומחיות עמוקה—כבר עשינו זאת.
- הרשאת ESIA. תורים דורשים SNILS ופוליסת ביטוח רפואי (OMS). אינטגרציה עם Gosuslugi היא חובה ולא טריוויאלית: חתימת בקשות, OAuth 2.0, הסמכת מערכת.
- ביצועים. שאילתות ישירות ל-EMIAS עבור כל הצגת לוח זמנים אינן מקובלות. הפתרון הוא סנכרון מקומי באמצעות סוכנים, המפחית את עומס ה-API פי 20–50.
ללא פתרונות אלה, האתר יעבוד בצורה לא תקינה או ייכשל בהסמכה.
איך מקבלים גישה ל-API של EMIAS?
התהליך כולל ארבעה שלבים:
- הגשת בקשה למחלקת טכנולוגיות המידע של מוסקבה (DIT).
- חתימה על הסכם שיתוף מידע.
- קבלת תעודת לקוח עבור mTLS.
- קבלת סביבת בדיקה ותיעוד.
ה-API של EMIAS משתמש ב-WCF או REST. עבור ניהול לוחות זמנים, השירות הוא ScheduleService.
לקוח SOAP עבור EMIAS
אם EMIAS מספקת WSDL, אנו בונים לקוח SOAP עם תמיכת mTLS:
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 { $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; } } SNILS ופוליסת OMS הם שדות חובה. זה מבדל את EMIAS מהותית ממערכות MIS מסחריות.
אימות מטופל דרך Gosuslugi
מכיוון ש-EMIAS דורשת SNILS, אינטגרציה עם ESIA לאימות מטופלים היא הצעד ההגיוני הבא. המטופל מתחבר דרך Gosuslugi → המערכת מקבלת את ה-SNILS והנתונים שלו → מעבירה אותם ל-EMIAS.
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); } } אינטגרציה עם ESIA היא פרויקט נפרד עם דרישות הסמכת מערכת.
למה יש צורך בסנכרון לוחות זמנים
שאילתות ישירות ל-EMIAS עבור כל הצגת לוח זמנים הן איטיות ומוגבלות בקצב. השוואת גישות:
| גישה | מהירות | עומס EMIAS | מורכבות |
|---|---|---|---|
| שאילתה ישירה | 2–5 שניות | גבוה | נמוכה |
| סנכרון מקומי | 10–50 אלפיות שנייה | נמוך | בינונית |
סנכרון מקומי מהיר פי 20–50 ומפחית את העומס על ה-API הממשלתי. סוכן כל 5–15 דקות טוען משבצות לטבלה מקומית:
class EmiasSyncAgent { public function syncSchedule(): string { $doctors = $this->getActiveDoctors(); $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__ . '();'; } } המשבצות מאוחסנות ב-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 { $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); } } , class EmiasSyncAgent { public function syncSchedule(): string { $doctors = $this->getActiveDoctors(); $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. האתר קורא מהטבלה המקומית, לא ישירות מ-EMIAS.
התנגשויות הזמנות בו-זמניות
משתמש בוחר משבצת של 15:00 → ממלא את הטופס → מישהו אחר הזמין את אותה משבצת דרך פורטל EMIAS. פתרון:
- כשהטופס נפתח, בצעו הזמנה רכה של המשבצת בטבלה המקומית (סמנו אותה).
- ההזמנה נשמרת למשך 5 דקות.
- בהגשה הסופית, כתבו ל-API של EMIAS.
- אם EMIAS מחזירה שגיאת "משבצת תפוסה", הציגו את המשבצות הפנויות הקרובות ביותר.
גישה זו מצמצמת התנגשויות למינימום (בפועל, פחות מ-5% דחיות) ומשפרת את נוחות המטופל.
שגיאות אינטגרציה אופייניות
בעיות נפוצות והפתרונות שלהן
- תעודת mTLS לא עובדת. בדקו את שרשרת התעודות: אתם צריכים תעודת לקוח שהונפקה על ידי DIT.
- לקוח SOAP דוחה את ה-WSDL. נסו לטעון את ה-WSDL מקומית ולהצביע על הקובץ—לפעמים זו מגבלת רשת.
- שגיאת הרשאת ESIA. ודאו שחתימת הבקשה נכונה ושה-URI של ההפניה תואם לזה שבהגדרות המערכת.
- פקיעת זמן לסוכן הסנכרון. הגדילו את זמן ביצוע הסוכן בהגדרות Bitrix או חלקו בקשות לקבוצות.
הימנעו מהמלכודות האלה—הזמינו אינטגרציה מקצועית.
מה כלול
| שלב | היקף העבודה |
|---|---|
| גישה | סיוע בקבלת גישה ל-API של EMIAS (תמיכה אדמיניסטרטיבית) |
| הגדרת mTLS | הנפקה והתקנה של תעודת הלקוח |
| לקוח SOAP | יישום הלקוח עבור SLOT_TIME ושיטות אחרות |
| סנכרון | סוכן לטעינה תקופתית של לוח הזמנים לטבלה המקומית |
| רכיב הזמנות | טופס עם שדות SNILS, פוליסת OMS, אינטגרציית ESIA אופציונלית |
| בדיקות | אימות בסביבת הבדיקה, טיפול בשגיאות |
| תיעוד | תיאור סכמת האינטגרציה, מדריך הפעלה |
לוחות זמנים משוערים: הליכים אדמיניסטרטיביים—1–3 חודשים, פיתוח טכני—6–12 שבועות לאחר קבלת הגישה. קבלו ייעוץ—נעריך את הפרויקט שלכם באופן אישי.
EMIAS — מערכת הבריאות הממשלתית של מוסקבה.







