Sports Club Website: From Schedule to Merch on 1C-Bitrix
Imagine: a fan wants to buy a match ticket, select a specific seat on the stadium map, and also order a jersey with a player's name — all on one site. And it all must work smoothly under peak loads. We build such sites on 1C-Bitrix, where training schedules, tournament tables, a seat-selection ticket system, and a merch store coexist. Each block requires separate data architecture, and together — proper caching and tagging. Our experience shows that standard components only work with custom configuration of infoblocks and Highload blocks. Project cost is calculated individually — contact us for an estimate.
How to Design Data Structure for a Sports Club?
For a sports club, a hierarchy of several linked infoblocks is built:
- Teams — main infoblock linked to sport type, league, season. Properties: roster (link to "Athletes" infoblock), coaching staff, logo, uniform colors.
- Athletes — infoblock with detailed profiles: full name, position, number, anthropometry, uniform photo, season statistics (goals/points/assists stored in a separate Highload block for fast retrieval).
- Matches and Training Sessions — Highload block (
b_hlblock_schedule), because over several seasons there are thousands of records. Fields: date/time, type (training/match/friendly), home team, away team, stadium, status (scheduled/in progress/completed/postponed), score. - Tournaments — infoblock linked to season. The tournament table is generated by a custom component based on match results from the Highload block.
Links between infoblocks are implemented via a property of type "Link to elements" (E) or via Highload directories if performance is needed on selections.
Why Use Highload Blocks for Scheduling?
The training and match schedule is the "hottest" section of the site. Fans check upcoming games, coaches view training sessions, admins update results in real time.
Highload block is chosen for a reason: with 300+ matches per season and 5-6 teams in a club, a regular infoblock starts to lag on complex filters. A Highload block stores data in a separate MySQL table, queries go directly without the overhead of the infoblock API. Comparison: Highload blocks process queries 5 times faster than infoblocks on selections of 10,000 records.
Frontend filtering: by team, by event type, by month. The component renders a calendar grid with color indicators — gray for training, green for home matches, blue for away. For SEO, each match gets its own detail page with a human-readable URL like /matches/2024-25/spartak-vs-dinamo-12-10/.
Cache is tagged, tied to the schedule_updated tag. When any Highload block element is updated via the HighloadBlockOnAfterUpdate event handler, only this tag is cleared, not the entire site cache.
How the Ticket System with Seat Selection Works
This is the key and most technically complex part of the project. The standard sale module in Bitrix is designed for items in the cart — add, checkout, pay. A ticket for a specific seat in a specific sector is a completely different mechanism.
Architecture solution: Each stadium (hall, arena) is described by an SVG file, where each seat is a separate <rect> or <circle> element with attributes data-sector, data-row, data-seat. The SVG is loaded into the browser, a JavaScript handler takes care of interactivity: highlight on hover, seat selection on click, display of occupied seats in gray.
Storage of seats and states: A Highload block hl_stadium_seats is created with fields:
| Field | Type | Purpose |
|---|---|---|
UF_STADIUM_ID |
Number | Link to stadium |
UF_SECTOR |
String | Sector code (A, B, C...) |
UF_ROW |
Number | Row number |
UF_SEAT |
Number | Seat number |
UF_CATEGORY |
Directory | Category (VIP, standard, fan zone) |
UF_PRICE_ZONE |
Directory | Price zone |
UF_SVG_ID |
String | SVG element ID for mapping |
For each match, a booking table is created — another Highload block hl_ticket_bookings:
| Field | Type | Purpose |
|---|---|---|
UF_MATCH_ID |
Number | Match ID from schedule |
UF_SEAT_ID |
Number | Seat ID from hl_stadium_seats |
UF_STATUS |
List | free / reserved / sold / blocked |
UF_ORDER_ID |
Number | Order ID in sale module |
UF_RESERVED_AT |
Datetime | Reservation time (for auto-release) |
UF_USER_ID |
Number | Buyer |
Purchase process step by step:
- User opens the match page, the SVG scheme loads.
- AJAX request to REST controller gets the array of occupied seats for this match. JavaScript colors them gray and removes the click handler.
- User clicks on a free seat — it is marked as
reservedinhl_ticket_bookingswith a timestamp. The reservation lives for 15 minutes, then a cron agent (CTicketReserveAgent) clears expired ones. - Selected seats are added to the cart of the
salemodule as product items. For this, each price zone is represented by a trade offer in the catalog. The cart propertySEAT_INFOstores serialized data about the specific seat. - Checkout is standard —
sale.order.ajaxwith a customized template. On successful payment, the status changes tosold, a PDF ticket with QR code is generated via the TCPDF library. - The QR contains a signed token (HMAC-SHA256), which is verified at the entrance by a scanner.
Concurrent access is critical. Two fans must not book the same seat. Solution: UPDATE ... WHERE UF_STATUS = 'free' with affected rows check. If 0 returned — seat already taken, frontend shows notification and redraws SVG.
Performance of SVG scheme on mobile
A stadium with 10,000 seats means 10,000 DOM elements. On mobile devices, this causes lags. Optimization: Canvas rendering for the overview with a switch to SVG when zooming into a specific sector. Or splitting by sectors — first select a sector on a simplified scheme, then load the detailed SVG of only the selected sector.Why Connect Tournament Tables via Custom Component?
The custom component custom:tournament.table aggregates data from the Highload block of matches: calculates points (3 for win, 1 for draw), goal difference, sorts. The result is cached with the tag tournament_{ID}, cleared when the score of any match in that tournament is updated.
For team sports with playoffs, the component can render a playoff bracket via SVG — pairs, winners, connection lines between rounds.
Athlete Profiles
The athlete detail page includes: photo, biography, career achievements (timeline via infoblock property "multiple" — club, years, achievements), current season statistics from the Highload block, photo/video gallery linked via CIBlockElement::GetProperty.
For SEO — micro-markup schema.org/Person with athlete in jobTitle field, linked to schema.org/SportsTeam.
Fan Zone and Merch Store
The news section is implemented with the standard news.list / news.detail component with a customized template. Photo and video gallery — infoblock linked to matches and athletes.
The merch store is a full-fledged online store on the catalog + sale module: jerseys, scarves, merchandise. Trade offers by size and color, integration with 1C for inventory management. It runs parallel to the ticket system but in a separate infoblock type so that the product catalog does not intersect with tickets.
Integration with Ticket Operators
If the club sells tickets not only through its website but also through Ticketland, Kassir.ru, or similar systems, synchronization is needed. This is implemented via the ticket operator's REST API: when a booking/sale occurs on the operator's side, a webhook updates the status in hl_ticket_bookings. And vice versa — a sale on the website sends data to the operator.
A cron synchronization agent runs every 2 minutes to fetch changes that may have failed to arrive via the webhook (network failures, timeouts).
Development Stages
| Stage | Scope of Work | Duration |
|---|---|---|
| Design | Infoblock and HL-block structure, SVG scheme prototypes | 2–3 weeks |
| Layout and Frontend | Responsive templates, interactive SVG scheme, calendar | 3–4 weeks |
| Ticket System Backend | Booking module, integration with sale, PDF tickets | 4–5 weeks |
| Content and Catalogs | Athlete profiles, tournament tables, merch store | 2–3 weeks |
| Integrations | Ticket operators, 1C, payment systems | 2–3 weeks |
| Testing | Load testing SVG (10,000 seats), concurrent booking | 1–2 weeks |
| Launch and Support | Deployment, agent monitoring, editor training | 1 week |
What's Included
- Full documentation on infoblock structure, HL blocks, caching settings.
- Source code of all custom components and agents in the repository.
- Editor training: how to add matches, update statistics, upload SVG schemes.
- Warranty support for 1 month after launch — bug fixes, consultations.
We guarantee correct system operation under peak loads of up to 10,000 concurrent visitors. Contact us for a project estimate — we will prepare a commercial proposal. Get a consultation on your sports website architecture.







