Integration of 1C-Bitrix with 1C:Medicine

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Integrating 1C-Bitrix with 1C:Medicine

1C:Medicine is a family of configurations for medical organisations: "Hospital", "Polyclinic", "Medical Laboratory". The configurations run on the 1C:Enterprise 8 platform and, unlike most other MIS systems, are well known to developers working within the 1C ecosystem. Integration with 1C-Bitrix is implemented via 1C HTTP services, COM objects, or exchange through an intermediate database.

Integration Methods

1C HTTP services (preferred). An HTTP service is created in the 1C:Medicine configuration that accepts REST requests from 1C-Bitrix. This is the most modern and manageable approach.

COM object (Windows server only). Direct invocation of 1C from PHP via COM — fast for low volumes, but ties you to Windows and creates concurrency issues.

Intermediate database. 1C:Medicine writes data (schedules, test results) to a shared PostgreSQL/MySQL database; 1C-Bitrix reads from there. An asynchronous approach that requires no changes to 1C if it already supports data export.

HTTP services are treated as the primary method.

HTTP Service in 1C:Medicine

An HTTP service is created in the 1C Configurator (General → HTTP Services):

Name: MedicalAPI
RootURL: /medapi
Version: 1.0.0

Methods (URL templates):

  • GET /medapi/doctors — list of physicians
  • GET /medapi/schedule/{doctorId}/{date} — physician schedule
  • POST /medapi/appointments — create appointment
  • DELETE /medapi/appointments/{id} — cancel appointment

Method handler in 1C (built-in language):

Function GetSchedule(Request)
    Response = New HTTPServiceResponse(200);
    Response.Headers["Content-Type"] = "application/json; charset=utf-8";

    DoctorId = Request.URLParameters["doctorId"];
    SessionDate = Date(Request.URLParameters["date"]);

    // Query the schedule register
    Query = New Query();
    Query.Text = "
    |SELECT
    |    DoctorSchedule.StartTime,
    |    DoctorSchedule.EndTime,
    |    DoctorSchedule.SlotStatus,
    |    DoctorSchedule.ClinicRoom
    |FROM
    |    InformationRegister.DoctorSchedule AS DoctorSchedule
    |WHERE
    |    DoctorSchedule.Doctor.UniqueIdentifier = &DoctorId
    |    AND DoctorSchedule.Date = &Date
    |    AND DoctorSchedule.SlotStatus = Enum.SlotStatuses.Free";

    Query.SetParameter("DoctorId", DoctorId);
    Query.SetParameter("Date", SessionDate);

    Result = Query.Execute().Choose();
    Slots = New Array();

    While Result.Next() Do
        SlotData = New Structure("start,end,cabinet");
        SlotData.start   = Format(Result.StartTime, "DF=HH:mm");
        SlotData.end     = Format(Result.EndTime, "DF=HH:mm");
        SlotData.cabinet = Result.ClinicRoom.Number;
        Slots.Add(SlotData);
    EndDo;

    Response.SetBodyFromString(WriteJSON(Slots));
    Return Response;
EndFunction

PHP Client for the 1C:Medicine HTTP Service

class OneCMedicinaClient
{
    private string $baseUrl; // http://1c-server:8080/medicine/hs/medapi
    private string $username;
    private string $password;

    public function getSchedule(string $doctorGuid, string $date): array
    {
        return $this->request('GET', "/schedule/{$doctorGuid}/{$date}");
    }

    public function createAppointment(array $data): array
    {
        return $this->request('POST', '/appointments', [
            'slotDate'    => $data['date'],
            'slotTime'    => $data['time'],
            'doctorGuid'  => $data['doctor_guid'],
            'patient'     => [
                'lastName'   => $data['last_name'],
                'firstName'  => $data['first_name'],
                'middleName' => $data['middle_name'] ?? '',
                'birthDate'  => $data['birth_date'],
                'phone'      => $data['phone'],
                'email'      => $data['email'],
                'snils'      => $data['snils'] ?? '',
            ],
            'serviceCode' => $data['service_code'] ?? '',
        ]);
    }

    private function request(string $method, string $path, array $body = []): array
    {
        $ch = curl_init($this->baseUrl . $path);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST  => $method,
            CURLOPT_USERPWD        => "{$this->username}:{$this->password}", // Basic Auth in 1C
            CURLOPT_HTTPHEADER     => ['Content-Type: application/json; charset=utf-8'],
            CURLOPT_POSTFIELDS     => $body ? json_encode($body, JSON_UNESCAPED_UNICODE) : null,
            CURLOPT_TIMEOUT        => 10,
        ]);

        $json     = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            throw new \RuntimeException("1C:Medicine API error {$httpCode}");
        }

        return json_decode($json, true) ?? [];
    }
}

Important: 1C:Enterprise does not natively support parallel requests to a single infobase without client connection licences. Under high load, a connection pool or caching on the 1C-Bitrix side is required.

Directory Synchronisation

The list of physicians, their specialisations, and rooms is synchronised from 1C into a 1C-Bitrix infoblock:

class OneCMedicDoctorSync
{
    public function syncDoctors(): void
    {
        $doctors = $this->onecClient->request('GET', '/doctors');

        foreach ($doctors as $doctor) {
            $existingId = $this->findDoctorByGuid($doctor['guid']);

            $fields = [
                'NAME'           => $doctor['fullName'],
                'ACTIVE'         => $doctor['active'] ? 'Y' : 'N',
                'IBLOCK_ID'      => DOCTORS_IBLOCK_ID,
                'IBLOCK_SECTION_ID' => $this->getSpecializationSectionId($doctor['specialization']),
            ];

            $props = [
                'DOCTOR_GUID'        => $doctor['guid'],
                'SPECIALIZATION'     => $doctor['specialization'],
                'CABINET_NUMBER'     => $doctor['cabinet'],
                'EXPERIENCE_YEARS'   => $doctor['experienceYears'],
                'ACADEMIC_DEGREE'    => $doctor['academicDegree'],
            ];

            if ($existingId) {
                $el = new \CIBlockElement();
                $el->Update($existingId, $fields);
                \CIBlockElement::SetPropertyValuesEx($existingId, DOCTORS_IBLOCK_ID, $props);
            } else {
                $el = new \CIBlockElement();
                $newId = $el->Add(array_merge($fields, ['PROPERTY_VALUES' => $props]));
            }
        }
    }
}

Scope of Work

  • Analysis of the specific 1C:Medicine configuration and available registers
  • Development of an HTTP service on the 1C side (jointly with a 1C developer)
  • PHP client for the HTTP service with caching
  • Physician directory synchronisation into the 1C-Bitrix infoblock
  • Online appointment component with form
  • Patient notifications after booking

Timeline: 6–10 weeks with a 1C developer in the team. HTTP service development on the 1C side — 2–4 weeks; PHP part — 3–6 weeks.