Feedback Module Development for 1C-Bitrix
The standard bitrix:main.feedback component can send an email and save a record to an infoblock. This is sufficient for a landing page with a single form. As soon as there are multiple forms with different fields, department routing, CRM integration, anti-spam, and a conversion dashboard — the standard solution breaks down. A feedback module is a full-featured form management system with analytics.
Data Model
Module vendor.feedback:
-
b_vendor_feedback_form— forms: id, code, name, fields_schema (JSON), submit_action (JSON: email/crm/webhook), success_message, redirect_url, is_active, spam_protection (JSON) -
b_vendor_feedback_submission— submissions: id, form_id, data (JSON), user_id, ip, user_agent, page_url, utm_source, utm_medium, utm_campaign, status (new/processed/spam), created_at -
b_vendor_feedback_attachment— submission file attachments: id, submission_id, file_id -
b_vendor_feedback_stat— form statistics (daily snapshots): form_id, date, views, submissions, conversion
Form Builder
The form field schema is stored in fields_schema as JSON. Example:
[
{"type": "text", "name": "name", "label": "Name", "required": true},
{"type": "phone", "name": "phone", "label": "Phone", "required": true, "mask": "+7 (999) 999-99-99"},
{"type": "email", "name": "email", "label": "Email", "required": false},
{"type": "select", "name": "dept", "label": "Department", "options": ["Sales", "Support", "Accounting"]},
{"type": "file", "name": "doc", "label": "Document", "accept": ".pdf,.doc,.docx", "max_size_mb": 5},
{"type": "textarea","name": "message","label": "Message", "required": true}
]
The vendor:feedback.form component renders the form from the schema without requiring template changes when fields are added.
Submission Handling
class SubmissionHandler
{
public function handle(int $formId, array $postData, array $files): HandleResult
{
$form = FormTable::getById($formId)->fetch();
// Validate against the field schema
$validator = new FormValidator($form['FIELDS_SCHEMA']);
if (!$validator->validate($postData)) {
return HandleResult::validationError($validator->getErrors());
}
// Anti-spam check
if (!$this->spamChecker->check($postData, $form['SPAM_PROTECTION'])) {
return HandleResult::spam();
}
// Save the submission
$submissionId = SubmissionTable::add([
'FORM_ID' => $formId,
'DATA' => $postData,
'IP' => $_SERVER['REMOTE_ADDR'],
'PAGE_URL' => $_SERVER['HTTP_REFERER'] ?? '',
'UTM_SOURCE' => $_COOKIE['utm_source'] ?? '',
// ...
])->getId();
// Upload files
foreach ($files as $fieldName => $file) {
$fileId = \CFile::SaveFile(\CFile::MakeFileArray($file['tmp_name']), 'feedback');
AttachmentTable::add(['SUBMISSION_ID' => $submissionId, 'FILE_ID' => $fileId]);
}
// Execute actions (email, CRM, webhook)
$this->dispatchActions($form['SUBMIT_ACTION'], $submissionId, $postData);
return HandleResult::success();
}
}
Routing and Actions
The submit_action field defines what happens after form submission:
{
"email": {"to": ["[email protected]"], "template": "feedback_sales"},
"crm": {"type": "lead", "responsible_id": 42, "fields_map": {"name": "TITLE", "phone": "PHONE"}},
"webhook": {"url": "https://n8n.company.com/webhook/feedback", "method": "POST"}
}
Multiple actions execute sequentially. If one action fails (e.g., CRM is unavailable), the rest continue and the error is logged.
Anti-Spam
Three levels of protection:
- Honeypot — a hidden field in the form, automatically filled by bots
- Timing check — the form cannot be submitted faster than 3 seconds after loading (JavaScript + server-side)
-
Rate limiting — no more than 3 submissions per IP per hour: checked against
b_vendor_feedback_submission
reCAPTCHA v3 is connected as an optional module.
Analytics and Conversion
The form view counter is incremented via AJAX (a 1-pixel request when the form enters the viewport). Conversion = submissions / views:
In the admin dashboard:
- Form funnel: views → started filling → submitted → marked as spam
- UTM breakdown: which sources bring high-conversion submissions
- Average form fill time
- Hourly heat map: when submissions peak
Development Timeline
| Stage | Duration |
|---|---|
| ORM tables, form schema builder | 1 day |
| Form rendering from schema, validation | 1 day |
| Submission handler, file uploads | 1 day |
| Email, CRM, Webhook actions | 2 days |
| Anti-spam (honeypot, rate limit) | 1 day |
| View counter, statistics | 1 day |
| Admin interface, submission viewer | 2 days |
| Testing | 1 day |
Total: 10 working days. Integration with a specific CRM (Bitrix24, amoCRM, RetailCRM) is estimated during the scoping stage.







