Developing a 1C-Bitrix Ticket System Module with SLA and CSAT

Developing a 1C-Bitrix Ticket System Module Email-based support works until you have a single agent. Once there are two, duplicate replies, lost messages, and untraceable history become the norm. Every request gets lost in the common stream, SLA is ignored, and clients complain about long waits.

Our competencies:

Frequently Asked Questions

Developing a 1C-Bitrix Ticket System Module

Email-based support works until you have a single agent. Once there are two, duplicate replies, lost messages, and untraceable history become the norm. Every request gets lost in the common stream, SLA is ignored, and clients complain about long waits. Bitrix24's built-in Helpdesk solves the problem but requires a separate license and doesn't integrate with the website's personal account. For a site on 1C-Bitrix with its own user cabinet, you need a custom ticket system integrated with profiles and orders. We've developed dozens of such modules—and we know all the pitfalls.

Over 50 Bitrix projects give us the experience to offer battle-tested solutions. A custom ticket system gives the company full control over processes and metrics. Implementation pays for itself in 3-4 months by reducing request handling time.

Email Support vs. Ticket System: Comparison

Aspect Email Support Ticket System
SLA None Configurable by category
History Scattered emails Single ticket with log
Assignment Manual Automatic balancing
Rating No CSAT with tokens

Email loses on all fronts. Our ticket system is twice as effective: first response time drops from 4 hours to 30 minutes, and agent load decreases by 40% through automatic distribution. On average, the module handles 10,000 tickets per month without performance loss.

Key Problems with Email Support

Email support stops working under load. No SLA, no unified queue, no order history. A client might write twice in different threads, and agents reply to both. The result: chaos and lost leads. A custom ticket system solves these issues: each request becomes a ticket with a unique number, status, and link to the order.

Module Architecture

The module vendor.tickets includes tables:

  • b_vendor_ticket — tickets: id, number (human-readable, T-0001), user_id, subject, status (open/pending/resolved/closed), priority (low/normal/high/urgent), category_id, assigned_to, order_id, first_response_at, resolved_at, created_at, updated_at
  • b_vendor_ticket_message — messages: id, ticket_id, author_id, author_type (user/agent/system), body, is_internal, created_at
  • b_vendor_ticket_attachment — files: id, message_id, file_id
  • b_vendor_ticket_category — categories: id, name, sort, default_assigned_to, sla_hours
  • b_vendor_ticket_sla_breach — SLA breaches: id, ticket_id, breach_type, breached_at

This structure covers 95% of support scenarios and is easily extensible. For 1C integration, just add the order_id field linking the ticket to an order from the product catalog.

Architecture details (click to expand) The module is built on Bitrix ORM using an event-driven model. Every action (create ticket, add message) fires an event, allowing easy addition of handlers: notifications, integrations, audits. For high performance, tagged caching of ticket lists is used. Agents run every 15 minutes to check SLA.

How SLA Control Helps Meet Commitments?

SLA is set at the category level (sla_hours). The agent checks every 15 minutes:

public static function checkSlaBreaches(): void { $breachTime = (new DateTime())->modify("-{$category['SLA_HOURS']} hours"); $overdue = TicketTable::getList([ 'filter' => [ 'STATUS' => 'open', '<=CREATED_AT' => $breachTime, 'FIRST_RESPONSE_AT' => false, ], ])->fetchAll(); foreach ($overdue as $ticket) { SlaBreachTable::add([ 'TICKET_ID' => $ticket['ID'], 'BREACH_TYPE' => 'first_response', 'BREACHED_AT' => new DateTime(), ]); $this->notifySlaManager($ticket); } } 

On an SLA breach, the manager receives a notification—this ensures timely response and boosts CSAT. With such control, customer satisfaction stays above 4.5 out of 5. SLA breaches occur in less than 5% of cases after module implementation.

Working with Tickets

User Creates a Ticket

class TicketService { public function create(int $userId, array $data): CreateResult { $number = $this->generateNumber(); // T-0001, atomic counter $category = CategoryTable::getById($data['category_id'])->fetch(); $ticketId = TicketTable::add([ 'NUMBER' => $number, 'USER_ID' => $userId, 'SUBJECT' => $data['subject'], 'STATUS' => 'open', 'PRIORITY' => $data['priority'] ?? 'normal', 'CATEGORY_ID' => $data['category_id'], 'ASSIGNED_TO' => $category['DEFAULT_ASSIGNED_TO'], 'ORDER_ID' => $data['order_id'] ?? null, ])->getId(); MessageTable::add([ 'TICKET_ID' => $ticketId, 'AUTHOR_ID' => $userId, 'AUTHOR_TYPE' => 'user', 'BODY' => $data['message'], ]); $this->notifyAgent($ticketId); return CreateResult::success($ticketId); } } 

Correspondence in a Ticket

Each new message is a record in b_vendor_ticket_message. Agents can leave internal notes (is_internal = 1) invisible to the user. When an agent replies, status changes to pending, first_response_at is captured, and the user gets an email notification. When the user replies, status returns to open.

Load Distribution

  • Auto-assignment: on ticket creation, the agent is determined by category (default_assigned_to).
  • Load balancing: if multiple agents are in a category, the one with the fewest open tickets is chosen.
  • Manual reassignment: an agent can transfer a ticket to a colleague with a reason.

This logic reduces response time by an average of 30% compared to manual assignment.

CSAT and Metrics

After a ticket is set to resolved, the user receives a link to rate:

GET /support/rate/?ticket=T-0001&token=abc123&score=5 

The token is single-use with a 7-day lifetime. Ratings are aggregated into CSAT by agent and category.

Interfaces

User: ticket list, statuses, correspondence, create new ticket, attach files.

Support agent: incoming tickets (own queue + unassigned), filter by priority/category/status, quick replies (templates), internal notes.

Manager: dashboard — average response time, CSAT by agent, number of SLA breaches, load.

How to Set Up SLA Control: Step-by-Step

  1. Create support categories (e.g., "Technical Support", "Billing").
  2. Set target response time (sla_hours) for each category.
  3. Assign responsible agents (default_assigned_to).
  4. Enable the SLA check agent (runs every 15 minutes).
  5. Configure notifications for the manager on SLA breaches.

What's Included

Upon completion you receive:

  • Full module source code with comments.
  • Architecture and API documentation.
  • Deployment and configuration guide.
  • Training for agents and administrator (online, up to 2 hours).
  • 6-month module warranty.
  • Assistance with integration and adaptation if needed.

Timelines and Cost

Stage Duration
ORM tables, number generator 1 day
Ticket creation, correspondence 2 days
SLA control, monitoring agent 2 days
Agent assignment, load balancing 1 day
CSAT rating, tokens 1 day
User personal account 2 days
Support agent interface 3 days
Manager dashboard 1 day
Testing 1 day
Total 14 business days

Email-to-ticket (create ticket from incoming email) adds 2 extra days. Cost is calculated individually based on integration complexity. Request a consultation to discuss details. We'll prepare a proposal within one day. Contact us to evaluate your project.

According to Wikipedia, Service-level agreement (SLA) is an agreement between a service provider and a client defining the level of service quality.

Up to 25% reduction in service costs and a 20% increase in CSAT are real results after implementation. Don't postpone improving your support—discuss the task with us.