Dry Cleaning Website Development on 1C-Bitrix
A dry cleaning website solves a specific problem: the customer must understand the cost of processing their item and leave a request — ideally in one visit, without calls and clarifications. On 1C-Bitrix, this is implemented through a combination of infoblocks, Highload blocks with a price matrix, and an order form linked to CRM.
Service Catalog: Infoblock Structure
Dry cleaning services are grouped by categories: clothing, carpets and carpet floors, curtains and textiles, leather and suede, wedding dresses, upholstered furniture. Each category is a section of the Services infoblock. Elements within are specific services: "Dry cleaning of a down jacket", "Carpet cleaning 2×3 m", "Leather jacket restoration".
Infoblock element properties:
- PROPERTY_MATERIAL — material type (multiple, reference)
- PROPERTY_MIN_PRICE — cost from (for display in catalog)
- PROPERTY_DURATION — execution time in working days
- PROPERTY_COMPLEXITY — processing complexity (standard / advanced / premium)
- PROPERTY_PHOTO_BEFORE_AFTER — before/after gallery (multiple file)
For output, the bitrix:catalog.section.list component is used with a custom template. The service card shows a photo, price range, timeline, and a "Calculate Cost" button, which opens the calculator with the category pre-filled.
Cost Calculator with Price Matrix
The calculator is a key element of the website, and its architecture deserves detailed analysis.
Price matrix. The price depends on three parameters: item type, material, and degree of contamination. This creates a three-dimensional matrix stored in the Highload block CleaningPrices:
| Field | Type | Example Value |
|---|---|---|
| UF_ITEM_TYPE | Reference to directory | Down jacket |
| UF_MATERIAL | Reference to directory | Polyester |
| UF_CONTAMINATION | List | light / medium / heavy |
| UF_BASE_PRICE | Number | 1800 |
| UF_EXPRESS_COEFF | Number | 1.5 |
| UF_EXTRA_SERVICES | JSON | {"waterproofing": 500, "deodorization": 300} |
The ItemTypes and Materials directories are separate Highload blocks. This allows the manager to add new item types and materials without developer involvement. References between them specify allowed combinations: leather applies to a jacket, but not to bed linen.
Frontend logic. The calculator is implemented as a step-by-step form (wizard):
- Step 1 — Item type. Visual selection with icons: jacket, dress, carpet, curtains. When selected, an AJAX request loads available materials for this type
- Step 2 — Material. The list is filtered by item type. For inexperienced users — hints with texture photos
- Step 3 — Degree of contamination. Three options with visual examples: light (dust, surface stains), medium (old stains, odor), heavy (oil, paint, mold)
-
Step 4 — Additional services. Checkboxes: water-repellent coating, deodorization, moth repellent, packaging. Cost is pulled from the
UF_EXTRA_SERVICESfield - Result. Total cost with breakdown: base price + additional services. Optionally — cost of express processing (×UF_EXPRESS_COEFF)
Server side. The AJAX controller CleaningCalculator inherits from Bitrix\Main\Engine\Controller. The calculateAction() method accepts item type ID, material, contamination level, and an array of additional services. It makes a query from the Highload block through D7 ORM:
CleaningPricesTable::getList([
'filter' => [
'UF_ITEM_TYPE' => $itemTypeId,
'UF_MATERIAL' => $materialId,
'UF_CONTAMINATION' => $contamination
]
])
If an exact match is not found (the client selected a rare material), the default price for the item type is taken with a note "exact cost after inspection".
Matrix caching. On first request, the entire price matrix is loaded into Bitrix\Main\Data\Cache with the tag cleaning_prices. When any Highload block element is changed, the tag is cleared through the OnAfterUpdate handler. This eliminates database queries on each calculation.
Online Request with Courier Pickup
After cost calculation, the client fills out an order form:
- Contact information (phone, name)
- Pickup address (with suggestions via DaData API)
- Pickup date and time slot (selection from available options — an agent generates slots daily for 7 days ahead)
- Comment (description of contamination, special requests)
The request creates a lead in the Bitrix24 CRM module via REST API. The lead card is already filled in with: service, estimated cost, address, pickup slot. The manager only needs to confirm the order and assign a courier.
For SMS notifications, a provider is connected through the messageservice module. The client receives SMS at each stage: "Courier is on the way", "Items accepted", "Order ready", "Courier will deliver today from 2 to 4 PM".
Order Status Tracking by Number
A "Check Order Status" form is placed on the website. The client enters the order number and the last 4 digits of their phone number. The system finds the element in the Orders infoblock and displays the current status with a timeline:
| Stage | Status | Date |
|---|---|---|
| Request accepted | Completed | 03/12 |
| Courier picked up items | Completed | 03/13 |
| Inspection and assessment | Completed | 03/13 |
| Dry cleaning | In progress | — |
| Quality control | Pending | — |
| Delivery to client | Pending | — |
The status is updated by an operator in the admin panel or automatically via webhook from the dry cleaning accounting system (1C:Enterprise, StoryClean, custom ERP).
Loyalty Program
For regular customers, an accumulation system is implemented. The sale module is used with internal user accounts. When an order is paid, bonus points are accrued (the percentage from the amount is configured in the LoyaltySettings Highload block).
Mechanics:
- Registration by phone number (authorization via SMS code,
mainmodule with custom handler) - Personal account: order history, bonus balance, saved addresses
- Bonus redemption on the next order (limitation — no more than 30% of the order amount)
- Referral program: client shares a link, when a new client orders, both receive bonuses
The bonus balance is stored in the user's UF-field UF_BONUS_BALANCE. Accrual and redemption are logged in a separate BonusTransactions Highload block for transparency and audit capability.
SEO Optimization for Local Search
Dry cleaning is a local business. Main search queries contain geography: "dry cleaning of down jackets in Minsk", "carpet cleaning in Frunzensky District".
The following is configured:
- Schema.org
DryCleaningOrLaundrymicromarkup with address, working hours, service area - Landing pages for districts — through the
GeoPagesinfoblock with coordinate binding - Auto-generation of title and description from template: "Dry cleaning of {item_type} in {district} — from {min_price} rubles"
- "Before/after" pages with alt-tags by contamination type — work in image search
- Bitrix SEO module for managing robots.txt, sitemap.xml, canonical URLs
Component caching is configured taking geography into account: for each city/district — its own cache variant via CACHE_GROUPS.







