Beauty Salon Website Development on 1C-Bitrix
A beauty salon website works like a receptionist that never goes to lunch. A client selects a service, sees available stylists, books a convenient time — all without a phone call. If there's no online booking, the salon loses customers searching for "manicure nearby" at 11 PM who are ready to book immediately.
Let's explore the implementation on 1C-Bitrix: from the service catalog to the mechanics of online booking with free slot calculation.
Service Catalog: Infoblock Structure
Salon services are organized in an infoblock with section hierarchy: "Hairdressing," "Manicure and Pedicure," "Cosmetology," "Massage." Each section can contain subsections — "Haircuts," "Hair Coloring," "Skincare Treatments."
Properties of the "Services" Infoblock Element:
| Property | Type | Purpose |
|---|---|---|
| PRICE_FROM | number | Price "from" (depends on stylist) |
| DURATION_MIN | number | Duration in minutes |
| MASTER_LINK | E (multiple) | Link to stylists offering the service |
| CATEGORY_TAGS | string (multiple) | Tags: "for brides," "new" |
| CONTRAINDICATIONS | HTML | Contraindications (for cosmetology) |
| PREPARATION | HTML | Preparation for procedure |
Price "from" is a deliberate choice. In salons, price depends on stylist category (junior, stylist, senior stylist). The exact price is calculated after selecting a stylist — this requires an intermediate table "stylist — service — price."
Implemented through Highload Block MasterServicePrice with fields: UF_MASTER_ID, UF_SERVICE_ID, UF_PRICE. When selecting a service on the frontend, all stylists with their prices are pulled through DataManager::getList().
Online Booking with Stylist Slots
This is the key feature of the site and the most complex to implement. Clients expect a simple interface: select service, select stylist, see available times, click "Book." Behind this simplicity lies multi-level availability calculation logic.
Step 1: Select Service. Client chooses from the catalog. System determines duration (DURATION_MIN) and list of stylists offering the service (MASTER_LINK).
Step 2: Select Specific Stylist or "Any Available." If the client selects a specific stylist — work with their schedule. If "any" — iterate through all stylists and show a combined set of slots.
Step 3: Calculate Free Slots. Here the engineering begins.
Calculation data is stored in three Highload Blocks:
MasterSchedule — stylist's work schedule:
-
UF_MASTER_ID— stylist ID -
UF_DATE— date -
UF_WORK_START— shift start (HH:MM) -
UF_WORK_END— shift end -
UF_BREAK_START— break start -
UF_BREAK_END— break end
MasterBooking — existing bookings:
-
UF_MASTER_ID,UF_DATE,UF_TIME_START,UF_TIME_END,UF_CLIENT_ID,UF_SERVICE_ID,UF_STATUS
MasterDayOff — vacations, sick days, days off.
Algorithm for calculating free slots for a specific stylist on a specific date:
- Get work schedule from
MasterSchedule. If record not found or date inMasterDayOff— stylist unavailable - Create array of work minutes: from
UF_WORK_STARTtoUF_WORK_END, excluding break - Get all bookings from
MasterBookingwith statusconfirmedorpending - Subtract booked intervals from work minutes
- In remaining free intervals, find slots of duration >=
DURATION_MINof service - Split these slots into 15 or 30-minute intervals (configurable)
// Pseudocode for slot calculation
$freeIntervals = subtractIntervals($workIntervals, $bookedIntervals);
$slots = [];
foreach ($freeIntervals as $interval) {
$start = $interval['start'];
while ($start + $serviceDuration <= $interval['end']) {
$slots[] = $start;
$start += $stepMinutes;
}
}
Buffer Between Services. Between procedures, a technical break is often needed — 5-15 minutes for cabinet cleaning or tool preparation. The buffer is added to DURATION_MIN during slot calculation but not shown to the client.
Concurrent Access. Two clients simultaneously see the same free slot. The first clicks "Book" — the slot is locked. The second gets "time is taken, choose another." Locking is implemented via transaction: INSERT into MasterBooking + checking for no overlaps in one transaction.
Booking Confirmation. After booking, the client receives SMS (messageservice module) and email. A day before the visit — a reminder through a Bitrix agent. If the client doesn't confirm — the booking transitions to unconfirmed status, and the administrator decides whether to free the slot.
Integration with YCLIENTS and 1C:Beauty Salon
Most salons use an accounting system. The two most common:
YCLIENTS. Cloud platform with REST API. Main endpoints: /api/v1/book_record/ (create booking), /api/v1/book_dates/ (available dates), /api/v1/book_times/ (available slots). When integrating with YCLIENTS, the Bitrix site doesn't calculate slots itself — it requests them via API. Highload Blocks MasterSchedule and MasterBooking aren't needed in this case: YCLIENTS is the master system.
Downside: dependency on third-party API. If YCLIENTS is down — no booking on the site. Solution — cache the last known schedule and fall back to "submit a request" form.
1C:Beauty Salon. Exchange through 1C HTTP services or file exchange (XML). Synchronization of stylists, services, bookings. Usually works with 5-15 minute delay — not real-time.
Portfolio of Stylist Work
Portfolio infoblock with links to stylist and service. Key properties:
-
PHOTO_BEFORE/PHOTO_AFTER— file properties -
MASTER_LINK— link to stylist -
SERVICE_LINK— link to service -
DESCRIPTION— what was done
On the stylist's page, portfolio is filtered by MASTER_LINK. On the service page — by SERVICE_LINK. Before/after photos are displayed with a slider with divider — a popular pattern in the beauty industry.
Important: portfolio photos must be compressed. Salon clients often visit via mobile — 10 photos at 5 MB each will kill conversion. Bitrix can resize through CFile::ResizeImageGet(), but it's better to set up WebP conversion at the nginx level or through OnFileSave event handler.
Gift Certificates and Promotions
Gift certificates are implemented through the sale module. A certificate is a product in the catalog with a value. When purchased, a unique code is generated and saved in order properties (\Bitrix\Sale\Order → propertyCollection). The code is sent to the buyer via email as a PDF.
When using a certificate at the salon, the code is entered during checkout — the sale.discount module's discount coupon triggers. The certificate balance decreases by the service amount.
Promotions are simpler: a separate infoblock with start/end dates, links to services, condition text. Displayed on the homepage and in the catalog through <=DATE_ACTIVE_FROM / >=DATE_ACTIVE_TO filter.
Loyalty Program
Bonus points can be implemented two ways:
Through sale.discount. The module supports accumulative discounts and rules based on purchase amounts. Limitation — no flexible point accrual for specific actions (referral, review, birthday).
Through Custom Module. Highload Block LoyaltyBalance with fields UF_USER_ID, UF_POINTS, UF_HISTORY (serialized operation log). On each payment, the OnSaleOrderPaid handler accrues points by formula (usually 3-10% of amount). On redemption — balance check and order amount reduction.
Implementation Timeline
| Scale | Scope | Timeline |
|---|---|---|
| Single salon, up to 10 stylists | Catalog, booking (via YCLIENTS API), portfolio, promotions | 6-8 weeks |
| Salon with own booking system | + slot calculation in Bitrix, SMS reminders, certificates | 10-14 weeks |
| Salon chain | + multisite, unified client base, loyalty, 1C integration | 16-22 weeks |
What to Pay Attention To
Catalog page load speed is critical — clients compare multiple salons and leave if the page takes more than 2 seconds. Caching Bitrix components ('CACHE_TIME' => 3600) is mandatory for catalog and portfolio. The online booking page can't be cached — slot data must be current.







