Development of a 1C-Bitrix appointment booking module

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
    1177
  • 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

1C-Bitrix Appointment Booking Module Development

Appointment booking is a simplified version of resource booking tied to a specific specialist and time slot. Medical clinics, hair salons, auto repair shops, legal consultations. The scheme is the same everywhere: the client selects a service, a specialist, a date and time, and receives a confirmation.

Difference from Resource Booking

In resource booking, an object is reserved (a room, a car). In appointment booking — the time of a specific specialist. The specialist is a Bitrix user with an attached schedule. One specialist can see multiple clients on the same day at different hours. The schedule changes: days off, vacations, rescheduling.

Data Structure

The vendor.appointment module:

  • b_vendor_appt_staff — specialists: id, user_id (→ b_user), name, photo_file_id, services (JSON array of service IDs), is_active
  • b_vendor_appt_service — services: id, name, duration_minutes, iblock_element_id, is_active
  • b_vendor_appt_schedule — working schedule: id, staff_id, day_of_week (0–6), time_from, time_to, slot_duration_minutes
  • b_vendor_appt_exception — schedule exceptions: id, staff_id, date, type (day_off/custom), custom_from, custom_to
  • b_vendor_appt_appointment — appointments: id, staff_id, service_id, user_id, date, time_from, time_to, status, notes, created_at

Available Slot Generation

Slots are generated on the fly — storing them in the database is impractical. When availability is requested:

public function getAvailableSlots(int $staffId, string $date): array
{
    $dayOfWeek = (int) (new \DateTime($date))->format('N') % 7;
    $schedule  = StaffScheduleTable::getList([
        'filter' => ['=STAFF_ID' => $staffId, '=DAY_OF_WEEK' => $dayOfWeek],
    ])->fetch();

    if (!$schedule) return [];

    // Check exceptions
    $exception = ExceptionTable::getList([
        'filter' => ['=STAFF_ID' => $staffId, '=DATE' => $date],
    ])->fetch();

    if ($exception && $exception['TYPE'] === 'day_off') return [];

    $slots = $this->generateSlots(
        $exception['CUSTOM_FROM'] ?? $schedule['TIME_FROM'],
        $exception['CUSTOM_TO']   ?? $schedule['TIME_TO'],
        (int) $schedule['SLOT_DURATION_MINUTES']
    );

    // Subtract booked slots
    $booked = AppointmentTable::getList([
        'filter' => ['=STAFF_ID' => $staffId, '=DATE' => $date, '!STATUS' => 'cancelled'],
        'select' => ['TIME_FROM', 'TIME_TO'],
    ])->fetchAll();

    return $this->subtractBooked($slots, $booked);
}

Single-Flow Booking

On the frontend — a three-step widget:

  1. Service selection (cards or list from an info block)
  2. Specialist + date + time selection (AJAX slot update on date change)
  3. Contact details + confirmation

Each step is an AJAX request; data is stored in the session until final confirmation. After confirmation, a record is created in b_vendor_appt_appointment and notifications are sent.

Double-Booking Prevention

Between "the user selected a slot" and "the user confirmed" some time passes. During this time another user may book the same slot. Solution — a temporary lock:

// When a slot is selected — soft lock for 10 minutes
$lockKey = "appt_lock_{$staffId}_{$date}_{$timeFrom}";
\Bitrix\Main\Application::getInstance()->getManagedCache()->set($lockKey, $userId, 600);

At final save the following is verified: the lock belongs to the current user, plus a transactional check in the database.

CRM Integration

Optionally: when an appointment is created, a lead or contact is automatically created in CRM. If the user already exists in CRM (search by email/phone), the appointment is linked to the existing contact via b_crm_contact. CRM record:

$crmContactId = $this->findOrCreateCrmContact($appointmentData);
\Bitrix\Crm\Activity\Entity\PhoneCallTable::add([
    'OWNER_TYPE_ID' => \CCrmOwnerType::Contact,
    'OWNER_ID'      => $crmContactId,
    'SUBJECT'       => 'Appointment: ' . $service['NAME'],
    'START_TIME'    => new DateTime($date . ' ' . $timeFrom),
    'END_TIME'      => new DateTime($date . ' ' . $timeTo),
    'RESPONSIBLE_ID'=> $staff['USER_ID'],
]);

Schedule Management

The specialist can manage their schedule via the personal account or administrative section:

  • Change working hours for a specific day
  • Close a day entirely (vacation, sick leave)
  • View the list of their appointments for the day/week
  • Cancel or reschedule an appointment with client notification

Administrative section for managers: consolidated calendar for all specialists, manual appointment creation (for phone inquiries), utilisation statistics.

Notifications

  • SMS via gateway (configured in the module) upon creation and one hour before the appointment
  • Email with appointment details and a cancellation link
  • Notification to the specialist in Bitrix24 (if in use) or by email

Development Timeline

Stage Duration
Data model, schedules, exceptions 2 days
Slot generation, occupancy check 2 days
Three-step booking widget 3 days
Double-booking prevention 1 day
Specialist personal account 2 days
CRM integration (optional) 1 day
Notifications (email + SMS) 1 day
Testing 1 day

Total: 13 working days. SMS gateway is connected separately depending on the provider.