Development of Product Q&A System in 1C-Bitrix
"Questions and Answers" section on product page allows potential buyers to ask clarifying questions and get answers from manager or other buyers. This reduces support requests and works as UGC content for SEO. Bitrix has no standard component for this feature — it's built on custom ORM model.
Data Structure
For Q&A system two linked tables are sufficient. Table b_product_question:
| Field | Type | Purpose |
|---|---|---|
| ID | int | Primary key |
| PRODUCT_ID | int | Product ID |
| USER_ID | int | User ID (NULL = guest) |
| AUTHOR_NAME | varchar(255) | Question author name |
| AUTHOR_EMAIL | varchar(255) | Email for answer notification |
| QUESTION | text | Question text |
| STATUS | enum | PENDING, APPROVED, REJECTED |
| CREATED_AT | datetime | Creation date |
Table b_product_answer (answers to questions):
| Field | Type | Purpose |
|---|---|---|
| ID | int | Primary key |
| QUESTION_ID | int | FK → b_product_question.ID |
| USER_ID | int | Who answered |
| AUTHOR_NAME | varchar(255) | Responder name |
| IS_OFFICIAL | tinyint(1) | Official answer from store |
| ANSWER | text | Answer text |
| STATUS | enum | PENDING, APPROVED |
| CREATED_AT | datetime | Date |
ORM classes ProductQuestionTable and ProductAnswerTable inherit from \Bitrix\Main\ORM\Data\DataManager. Relationship is formed via \Bitrix\Main\ORM\Fields\Relations\Reference for JOIN in single query.
Question Lifecycle
Each question goes through following stages:
- Buyer submits question → creates record
STATUS = PENDING. - Moderator receives email notification (email event
PRODUCT_QUESTION_NEW). - Moderator approves question (
STATUS = APPROVED) — question becomes visible on page. - Manager or other buyer leaves answer →
b_product_answerwithSTATUS = PENDING. - If answer requires moderation — approved similarly. Official answers (
IS_OFFICIAL = 1) may auto-publish. - After first approved answer, question author receives email notification.
Notifications
Minimal set of email events:
-
PRODUCT_QUESTION_NEW— new question awaits moderation. Recipient: manager. -
PRODUCT_ANSWER_NEW— new answer awaits moderation (if answer moderation enabled). -
PRODUCT_QUESTION_ANSWERED— your question got an answer. Recipient: question author byAUTHOR_EMAIL.
Templates are created in Settings → Email Events. Variables passed via second parameter of CEvent::Send():
\CEvent::Send('PRODUCT_QUESTION_ANSWERED', SITE_ID, [
'QUESTION_TEXT' => $question['QUESTION'],
'ANSWER_TEXT' => $answer['ANSWER'],
'PRODUCT_NAME' => $productName,
'PRODUCT_URL' => $productUrl,
'AUTHOR_EMAIL' => $question['AUTHOR_EMAIL'],
'AUTHOR_NAME' => $question['AUTHOR_NAME'],
]);
Search in Questions
On pages with many questions (popular products) add AJAX search by question text. Query via ORM:
ProductQuestionTable::getList([
'filter' => [
'=PRODUCT_ID' => $productId,
'=STATUS' => 'APPROVED',
'%QUESTION' => $searchQuery,
],
'select' => ['ID', 'AUTHOR_NAME', 'QUESTION', 'CREATED_AT'],
'order' => ['CREATED_AT' => 'DESC'],
'limit' => 10,
]);
Symbol % before key in D7 filter sets LIKE search.
Answer Usefulness Voting
Additional layer — "Was answer helpful?" (yes/no). This is small separate table b_product_answer_vote with fields ANSWER_ID, USER_ID, IP, IS_HELPFUL. Aggregated counters (HELPFUL_COUNT, UNHELPFUL_COUNT) stored directly in b_product_answer for quick output without JOIN.
Admin Section
In /local/admin/product_questions.php display questions table with filters by status, product, date. Use standard CAdminList class for quick pagination and sorting implementation without hand-written HTML.
Development Timeframe
| Scope | Components | Duration |
|---|---|---|
| Basic | ORM models, question form, Q&A output, notifications, moderation in personal account | 4–6 days |
| Full | Buyer answers, question search, answer usefulness voting, admin section | 8–12 days |







