Developing a Ticket System Module for 1C-Bitrix
Email-based support works as long as there is only one support agent. Once there are two or more, problems start: duplicate responses, lost emails, inability to track conversation history for specific issues, lack of SLA. The built-in Helpdesk in Bitrix24 solves the problem, but requires a separate license. For a site on 1C-Bitrix with its own personal account, you need your own ticket system integrated with user profiles and orders.
Data Model
Module vendor.tickets:
-
b_vendor_ticket— tickets: id, number (human-readable, T-2024-0001), user_id, subject, status (open/pending/resolved/closed), priority (low/normal/high/urgent), category_id, assigned_to (agent_id), order_id (optional), first_response_at, resolved_at, created_at, updated_at -
b_vendor_ticket_message— ticket messages: id, ticket_id, author_id, author_type (user/agent/system), body, is_internal (internal note), 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 (first_response/resolution), breached_at
Creating a Ticket by User
class TicketService
{
public function create(int $userId, array $data): CreateResult
{
$number = $this->generateNumber(); // T-2024-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();
// First message
MessageTable::add([
'TICKET_ID' => $ticketId,
'AUTHOR_ID' => $userId,
'AUTHOR_TYPE' => 'user',
'BODY' => $data['message'],
]);
// Notify support agent
$this->notifyAgent($ticketId);
return CreateResult::success($ticketId);
}
}
Conversation in the Ticket
Each subsequent message is a new record in b_vendor_ticket_message. Agents can leave internal notes (is_internal = 1) that the user cannot see, but other agents can. When an agent replies:
- Ticket status changes to
pending(waiting for user response) -
first_response_atis recorded (if this is the first response) - User receives an email notification
When a user replies:
- Status changes to
open - Agent receives notification
SLA Control
SLA is set at the category level (sla_hours). An 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, // no first response
],
])->fetchAll();
foreach ($overdue as $ticket) {
SlaBreachTable::add([
'TICKET_ID' => $ticket['ID'],
'BREACH_TYPE' => 'first_response',
'BREACHED_AT' => new DateTime(),
]);
// Notify support manager
$this->notifySlaManager($ticket);
}
}
Agent Assignment and Queues
-
Auto-assignment: when a ticket is created, the agent is selected by category (field
default_assigned_to) - Load balancing: if multiple agents are in the queue, the one with fewer open tickets is selected
- Manual reassignment: an agent can transfer the ticket to a colleague with a reason specified
Support Quality Rating
After moving the ticket to resolved, the user is sent a link to rate the support:
GET /support/rate/?ticket=T-2024-0001&token=abc123&score=5
The token is one-time, with a 7-day lifespan. Ratings are aggregated into a CSAT metric by agent and by category.
Personal Account and Administrative Interface
User: list of their tickets, statuses, conversation, create new ticket, attach file.
Support Agent: incoming tickets (their queue + unassigned), filter by priority/category/status, quick replies (templates), internal notes, change history.
Manager: dashboard — average response time, CSAT by agents, number of SLA breaches, load by agents.
Development Timeline
| Stage | Duration |
|---|---|
| ORM-tables, number generator | 1 day |
| Creating tickets, conversation | 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 working days. Email-to-ticket (create ticket from incoming email) — additional 2 days.







